使用AOP动态调用WebService(转载)

方法简介:用AOP的原理实现了WebService的动态调用,实际上,是调用接口类的方法,然后使用反射得到该方法的返回值,参数等,然后再构造一个WebService的代理类,动态编译后调用返回值。

 首先定义一个WebService如下。其中使用了FaibClass.Data数据框架

1 using System; 2 using System.Web; 3 using System.Web.Services; 4 using System.Web.Services.Protocols; 5 using System.Xml.Serialization; 6 using Test.Model; 7 using Test.DA; 8 using FaibClass.Data; 9 10 [WebService(Namespace = "http://tempuri.org/")] 11 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 12 public class Service : System.Web.Services.WebService 13 { 14    public Service () { 15    } 16    [WebMethod] 17    public TCompanyType ATest_GetCompanyType() 18    { 19        ATCompanyType da = new ATCompanyType(); 20        da.AccessOptions = AccessOptions.SubEntityList; 21        //排除引用实体属性 22        da.PropertyFilter = new DebarredAttributes(typeof(ReferenceEntityAttribute)); 23        //列出分类 24        return da.Get("Name='大类'", (string[])null); 25    } 26    [WebMethod] 27    public TCompany ATest_GetFirstCompany() 28    { 29        return new ATCompany().Get(null); 30    } 31    [WebMethod] 32    public TCompanies ATest_GetCompanies() 33    { 34        return new ATCompany().Select(); 35    } 36    [WebMethod] 37    [XmlInclude(typeof(TCompany))] 38    public bool ATest_Insert(TCompany info) 39    { 40        return true; 41    } 42    [WebMethod] 43    [XmlInclude(typeof(TCompanies))] 44    public bool ATest_InsertAll(TCompanies list) 45    { 46        return true; 47    } 48    [WebMethod] 49    public void ATest_TestNull() 50    { 51    } 52    private void ATest_ListSubType(TCompanyTypes list) 53    { 54        if (list == null) return; 55        foreach (TCompanyType type in list) 56        { 57            //该分类下的公司 58            ATest_ListSubCompany(type.Companies); 59            //该分类下的子类 60            ATest_ListSubType(type.SubCompanyTypes); 61        } 62    } 63 64    //列出分类公司下面的子公司 65    private void ATest_ListSubCompany(TCompanies companies) 66    { 67        if (companies == null) return; 68        foreach (TCompany company in companies) 69        { 70            ATest_ListSubCompany(company.SubCompanies); 71        } 72    } 73 }

客户端也定义一个与之相似的类,暂将它称为接口类,因为它并不实现操作,只是为AOP调用提供方法信息,但是返回值都为null,即不操作。

1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using FaibClass.Data; 5 using Test.Model; 6 7 using FaibClass.Dynamic.WebService; 8 9 namespace Test 10 { 11    [DynamicWebService1("ATest_{0}")] 12    public class ATest : DynamicWebService 13    { 14        public TCompanyType GetCompanyType() 15        { 16            return null; 17        } 18        public TCompany GetFirstCompany() 19        { 20            return null; 21        } 22        public TCompanies GetCompanies() 23        { 24            return null; 25        } 26        public bool Insert(TCompany info) 27        { 28            return false; 29        } 30        public bool InsertAll(TCompanies list) 31        { 32            return true; 33        } 34        public void TestNull() 35        { 36        } 37    } 38 }

前台调用如下:

1            ATest test = new ATest(); 2            test.TestNull(); 3            TCompanyType type = test.GetCompanyType(); 4            ListSubType(type.SubCompanyTypes); 5            Console.WriteLine(test.GetFirstCompany().Name); 6            Console.WriteLine(test.GetCompanies()[0].Name); 7            TCompany a = new TCompany(); 8            a.Name = "dfdf"; 9            TCompanies list = new TCompanies(); 10            list.Add(a); 11            Console.WriteLine(test.InsertAll(list));

下面将一一对每个类进行说明。
    一、自定义代理属性 DynamicWebServiceAttribute。

1 //******************************************************************* 2 // 模块:动态WebService属性的基类 3 // 日期:2009-8-23 0:24 4 // 作者:Faib 5 // 版权:Copyright Faib Studio 2009 6 // 官网: http://www.faib.net.cn 7 // 邮箱:faib920@126.com 8 // 备注: 9 //******************************************************************* 10 using System; 11 using System.Runtime.Remoting.Proxies; 12 using System.Runtime.Remoting; 13 using System.Runtime.Remoting.Contexts; 14 using System.Runtime.Remoting.Activation; 15 16 using FaibClass.Dynamic.Configuration; 17 18 namespace FaibClass.Dynamic.WebService 19 { 20    /// <summary> 21    /// 动态WebService属性的基类。 22    /// </summary> 23    [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] 24    public class DynamicWebServiceAttribute : ProxyAttribute 25    { 26        string m_match; 27 28        public DynamicWebServiceAttribute(string match) 29        { 30            m_match = match; 31        } 32 33        /// <summary> 34        /// 创建实例。 35        /// </summary> 36        /// <param name="serverType"></param> 37        /// <returns></returns> 38        public override MarshalByRefObject CreateInstance(Type serverType) 39        { 40            DynamicWebServiceSettings setting = DynamicWebServiceConfiguration.Settings[this.GetType().FullName]; 41            //创建初始对象 42            MarshalByRefObject mobj = base.CreateInstance(serverType); 43            if (setting != null) 44            { 45                RealProxy realProxy = new AspectDynamicWebServiceProxy(setting, m_match, serverType, mobj); 46                //经过代理后返回透明代理 47                return realProxy.GetTransparentProxy() as MarshalByRefObject; 48            } 49            return mobj; 50        } 51 52        /// <summary> 53        /// 匹配符。 54        /// </summary> 55        public string Match 56        { 57            get { return m_match; } 58            set { m_match = value; } 59        } 60    } 61 }

客户端还要为每一个WebService定义一个DynamicWebServiceAttribute的继承类,如

1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 using FaibClass.Dynamic.WebService; 6 7 namespace Test 8 { 9    internal class DynamicWebService1 : DynamicWebServiceAttribute 10    { 11        public DynamicWebService1(string match) : base(match){} 12    } 13 } 14

就是ATest上的那个特性,该类再在app.config里定义相应的webservice调用参数,后面再介绍。这里的Match你可能发现了,就是 webservice里方法名与ATest里的匹配方式。

二、代理处理类 AspectDynamicWebServiceProxy 核心就在这里了

  1 //*******************************************************************   2 // 模块:动态调用WebService的代理处理类   3 // 日期:2009-8-23 0:35   4 // 作者:Faib   5 // 版权:Copyright Faib Studio 2009   6 // 官网: http://www.faib.net.cn   7 // 邮箱:faib920@126.com   8 // 备注:   9 //******************************************************************* 10 using System; 11 using System.Text; 12 using System.Collections; 13 using System.Collections.Generic; 14 using System.Runtime.Remoting.Proxies; 15 using System.Runtime.Remoting.Messaging; 16 using System.Runtime.Remoting; 17 using System.Runtime.Remoting.Activation; 18 using System.Runtime.Remoting.Services; 19 using System.Web.Services.Description; 20 using System.Xml; 21 using System.CodeDom; 22 using System.CodeDom.Compiler; 23 using Microsoft.CSharp; 24 using System.Reflection; 25 26 using FaibClass.Data; 27 using FaibClass.Dynamic.Configuration; 28 29 namespace FaibClass.Dynamic.WebService 30 { 31    /// <summary> 32    /// 动态调用WebService的代理处理类。 33    /// </summary> 34    internal class AspectDynamicWebServiceProxy : RealProxy 35    { 36        MarshalByRefObject target; 37        DynamicWebServiceSettings m_setting; 38        string m_match; 39 40        /// <summary> 41        /// 构造代理类。 42        /// </summary> 43        /// <param name="myType"></param> 44        public AspectDynamicWebServiceProxy(Type myType) 45            : base(myType) 46        { 47        } 48        /// <summary> 49        /// 构造代理类。 50        /// </summary> 51        /// <param name="setting"></param> 52        /// <param name="match"></param> 53        /// <param name="myType"></param> 54        /// <param name="obj"></param> 55        public AspectDynamicWebServiceProxy(DynamicWebServiceSettings setting, string match, Type myType, MarshalByRefObject obj) 56            : base(myType) 57        { 58            this.m_setting = setting; 59            this.m_match = match; 60            target = obj; 61        } 62 63        public override IMessage Invoke(IMessage msg) 64        { 65            IMessage retMsg = msg; 66            if (msg is IConstructionCallMessage) 67            { 68                IConstructionCallMessage ccm = (IConstructionCallMessage)msg; 69                RemotingServices.GetRealProxy(target).InitializeServerObject(ccm); 70                ObjRef oRef = RemotingServices.Marshal(target); 71                RemotingServices.Unmarshal(oRef); 72                retMsg = EnterpriseServicesHelper.CreateConstructionReturnMessage 73                    (ccm, (MarshalByRefObject)this.GetTransparentProxy()); 74            } 75            else if (msg is IMethodCallMessage) 76            { 77                IMethodCallMessage mcm = (IMethodCallMessage)msg; 78                MethodInfo minfo = mcm.MethodBase as MethodInfo; 79                //调用WebService返回值 80                object result = DyamicCallWebService(minfo, mcm.Args); 81                if (result == null) 82                    retMsg = RemotingServices.ExecuteMessage(target, mcm); 83                else 84                    retMsg = new ReturnMessage(result, null, 0, null, mcm); 85            } 86            return retMsg; 87        } 88 89        /// <summary> 90        /// 动态调用WebService中的方法。 91        /// </summary> 92        /// <param name="method">方法名。</param> 93        /// <param name="args">方法参数。</param> 94        /// <returns>返回值。</returns> 95        private object DyamicCallWebService(MethodInfo method, object[] args) 96        { 97            Type agentType; 98            object agent = null; 99            string[] assemblies = m_setting.Assemblies.Split('|'); 100            //调用的方法名 101            string methodName = method.Name; 102            if (!string.IsNullOrEmpty(m_match)) 103            { 104                methodName = string.Format(m_match, methodName); 105            } 106            // 缓存键 107            string key = DataCacheKeyManager.GetServiceKey(m_setting.Type, method); 108            if (DataCache<object>.ContainsKey(key)) 109            { 110                agent = DataCache<object>.Get(key); 111                agentType = agent.GetType(); 112            } 113            else 114            { 115 116                CSharpCodeProvider icc = new CSharpCodeProvider(); 117                CompilerParameters cp = new CompilerParameters(); 118                //引用程序集 119                cp.ReferencedAssemblies.Add("mscorlib.dll"); 120                cp.ReferencedAssemblies.Add("System.dll"); 121                cp.ReferencedAssemblies.Add("System.Web.Services.dll"); 122                cp.ReferencedAssemblies.Add("System.Xml.dll"); 123                cp.ReferencedAssemblies.Add("FaibClass.Data2.dll"); 124                cp.ReferencedAssemblies.Add("FaibClass.Dynamic.dll"); 125                foreach (string ass in assemblies) 126                { 127                    cp.ReferencedAssemblies.Add(ass.Split(',')[1].Trim() + ".dll"); 128                } 129 130                StringBuilder classSource = new StringBuilder(); 131                //加入引用 132                classSource.Append("using System;\n"); 133                classSource.Append("using System.Text;\n"); 134                classSource.Append("using System.Web.Services;\n"); 135                classSource.Append("using System.Web.Services.Protocols;\n"); 136                classSource.Append("using System.Web.Services.Description;\n"); 137                classSource.Append("using System.Xml.Serialization;\n"); 138                classSource.Append("using System.Diagnostics;\n"); 139                classSource.Append("using System.ComponentModel;\n"); 140                classSource.Append("using System.CodeDom.Compiler;\n"); 141                classSource.Append("using FaibClass.Data;\n"); 142                classSource.Append("using FaibClass.Dynamic.WebService;\n"); 143                foreach (string ass in assemblies) 144                { 145                    classSource.Append("using " + ass.Split(',')[0].Trim() + ";\n"); 146                } 147                classSource.Append("\n"); 148                //定义特性 149                classSource.Append("[WebServiceBinding(Name = \"ServiceSoap\", Namespace = \"http://tempuri.org/\"), XmlInclude(typeof(MarshalByRefObject)), DesignerCategory(\"code\"), DebuggerStepThrough, GeneratedCode(\"Test\", \"1.0.0.0\")]\n"); 150                classSource.Append("public class DynamicWebService : DynamicSoapHttpClientProtocol\n"); 151                classSource.Append("{\n\tpublic DynamicWebService(){ base.Url = \"" + m_setting.Url + "\"; }"); 152                //方法开始======= 153                classSource.Append("\n\t[SoapDocumentMethod(\"http://tempuri.org/" + methodName + "\", RequestNamespace = \"http://tempuri.org/\", ResponseNamespace = \"http://tempuri.org/\", Use=SoapBindingUse.Literal, ParameterStyle=SoapParameterStyle.Wrapped)]"); 154                classSource.Append("\n\tpublic "); 155                //方法返回类型 156                if (method.ReturnType.FullName == "System.Void") 157                    classSource.Append("void"); 158                else 159                    classSource.Append(method.ReturnType.Name); 160                //方法参数 161                classSource.Append(" " + methodName + "("); 162                bool first = true; 163                ParameterInfo[] pinfos = method.GetParameters(); 164                foreach (ParameterInfo pinfo in pinfos) 165                { 166                    if (!first) classSource.Append(","); 167                    else first = false; 168                    classSource.Append(pinfo.ParameterType.Name + " " + pinfo.Name); 169                } 170                //================ 171                classSource.Append(")\n\t{\n\t\t"); 172                if (method.ReturnType.FullName != "System.Void") 173                    classSource.Append("return (" + method.ReturnType.Name + ")"); 174                classSource.Append("base.Invoke(\"" + methodName + "\", "); 175                if (pinfos.Length == 0) 176                    classSource.Append("new object[0]"); 177                else 178                { 179                    classSource.Append("new object[]{"); 180                    first = true; 181                    foreach (ParameterInfo pinfo in pinfos) 182                    { 183                        if (!first) classSource.Append(","); 184                        else first = false; 185                        classSource.Append(pinfo.Name); 186                    } 187                    classSource.Append("}"); 188                } 189                classSource.Append(")"); 190                if (method.ReturnType.FullName != "System.Void") 191                    classSource.Append("[0]"); 192                classSource.Append(";\n\t}\n}"); 193 194                CompilerResults cr = icc.CompileAssemblyFromSource(cp, classSource.ToString()); 195                int c = cr.Errors.Count; 196                agentType = cr.CompiledAssembly.GetTypes()[0]; 197                agent = Activator.CreateInstance(agentType); 198                DataCache<object>.Add(key, agent); 199            } 200 201            if (agent != null) 202            { 203                return agentType.GetMethod(methodName).Invoke(agent, args); 204            } 205            return null; 206        } 207    } 208 }

在invoke中,拦截了ATest的调用方法,DyamicCallWebService进行分析并构造WebServicw的代理类代码,这里使用了缓存,第一次调用 方法都要经过编译,以后就不用了。

   三、配置
DynamicWebServiceSectionHandler

1 //******************************************************************* 2 // 模块:WebService配置节的访问 3 // 日期:2009-8-12 9:22:24 4 // 作者:Faib 5 // 版权:Copyright Faib Studio 2009 6 // 官网: http://www.faib.net.cn 7 // 邮箱:faib920@126.com 8 // 备注: 9 //******************************************************************* 10 using System; 11 using System.Configuration; 12 using System.Xml; 13 14 namespace FaibClass.Dynamic.Configuration 15 { 16    /// <summary> 17    /// 处理WebService配置节的访问。 18    /// </summary> 19    public sealed class DynamicWebServiceSectionHandler : IConfigurationSectionHandler 20    { 21        /// <summary> 22        /// 创建动态WebService节处理程序 23        /// </summary> 24        /// <param name="parent">父对象。</param> 25        /// <param name="configContext">上下文件对象。</param> 26        /// <param name="section">Xml节点。</param> 27        /// <returns></returns> 28        public object Create(object parent, object configContext, XmlNode section) 29        { 30            return new DynamicWebServiceConfiguration(section); 31        } 32    } 33 }

DynamicWebServiceConfiguration

1 //******************************************************************* 2 // 模块:动态WebService 3 // 日期:2009-8-23 0:51 4 // 作者:Faib 5 // 版权:Copyright Faib Studio 2009 6 // 官网: http://www.faib.net.cn 7 // 邮箱:faib920@126.com 8 // 备注: 9 //******************************************************************* 10 using System; 11 using System.Xml; 12 using System.Configuration; 13 14 namespace FaibClass.Dynamic.Configuration 15 { 16    /// <summary> 17    /// 动态WebService配置。 18    /// </summary> 19    public sealed class DynamicWebServiceConfiguration 20    { 21        DynamicWebServiceDictionary m_dic; 22        static DynamicWebServiceDictionary m_dic1; 23 24        /// <summary> 25        /// 由XmlNode生成实例配置集合。 26        /// </summary> 27        /// <param name="section"></param> 28        internal DynamicWebServiceConfiguration(XmlNode section) 29        { 30            if (section == null) throw new ArgumentNullException(); 31 32            m_dic = new DynamicWebServiceDictionary(); 33            foreach (XmlNode node in section.SelectNodes("webservice")) 34            { 35                string type = node.Attributes["type"] != null ? node.Attributes["type"].Value : ""; 36                string url = node.Attributes["url"] != null ? node.Attributes["url"].Value : ""; 37                string assemblies = node.Attributes["assemblies"] != null ? node.Attributes["assemblies"].Value : ""; 38                if (!string.IsNullOrEmpty(type) && !string.IsNullOrEmpty(url)) 39                { 40                    m_dic.Add(type, new DynamicWebServiceSettings(type, url, assemblies)); 41                } 42            } 43        } 44 45        internal DynamicWebServiceDictionary settings 46        { 47            get { return m_dic; } 48        } 49 50        public static DynamicWebServiceDictionary Settings 51        { 52            get 53            { 54                if (m_dic1 == null) 55                { 56                    object obj = ConfigurationManager.GetSection("faibclass.dynamic.webService"); 57                    if (obj != null) 58                    { 59                        m_dic1 = ((DynamicWebServiceConfiguration)obj).settings; 60                    } 61                } 62                return m_dic1; 63            } 64        } 65    } 66 }

DynamicWebServiceDictionary

1 //******************************************************************* 2 // 模块:动态WebService配置字典 3 // 日期:2009-8-12 9:21:05 4 // 作者:Faib 5 // 版权:Copyright Faib Studio 2009 6 // 官网: http://www.faib.net.cn 7 // 邮箱:faib920@126.com 8 // 备注: 9 //******************************************************************* 10 using System; 11 using System.Collections; 12 13 namespace FaibClass.Dynamic.Configuration 14 { 15    /// <summary> 16    /// 动态WebService配置字典。 17    /// </summary> 18    public class DynamicWebServiceDictionary : DictionaryBase 19    { 20        internal void Add(string key, DynamicWebServiceSettings setting) 21        { 22            Dictionary.Add(key, setting); 23        } 24 25        /// <summary> 26        /// 获取本字典内的键集合。 27        /// </summary> 28        public ICollection Keys 29        { 30            get { return Dictionary.Keys; } 31        } 32 33        /// <summary> 34        /// 由键名返回对应的配置信息。 35        /// </summary> 36        /// <param name="key"></param> 37        /// <returns></returns> 38        public DynamicWebServiceSettings this[string key] 39        { 40            get 41            { 42                if (Dictionary.Contains(key)) 43                { 44                    return (DynamicWebServiceSettings)Dictionary[key]; 45                } 46                return null; 47            } 48        } 49    } 50 }

DynamicWebServiceSettings

1 //******************************************************************* 2 // 模块:动态WebService配置信息 3 // 日期:2009-8-23 0:12 4 // 作者:Faib 5 // 版权:Copyright Faib Studio 2009 6 // 官网: http://www.faib.net.cn 7 // 邮箱:faib920@126.com 8 // 备注: 9 //******************************************************************* 10 using System; 11 using System.Collections.Generic; 12 using System.Text; 13 14 namespace FaibClass.Dynamic.Configuration 15 { 16    /// <summary> 17    /// 动态WebService配置信息。 18    /// </summary> 19    public class DynamicWebServiceSettings 20    { 21        /// <summary> 22        /// 处理类型 23        /// </summary> 24        public string Type; 25        /// <summary> 26        /// WebService地址 27        /// </summary> 28        public string Url; 29        /// <summary> 30        /// 引用程序集 31        /// </summary> 32        public string Assemblies; 33 34        public DynamicWebServiceSettings(string type, string url, string assemblies) 35        { 36            Type = type; 37            Url = url; 38            Assemblies = assemblies; 39        } 40    } 41 }

app.config配置如下

<?xml version="1.0" encoding="utf-8" ?> <configuration>   <configSections>     <section name="faibclass.data.instance" type="FaibClass.Data.Configuration.DataInstanceSectionHandler, FaibClass.Data2" />     <section name="faibclass.dynamic.webService" type="FaibClass.Dynamic.Configuration.DynamicWebServiceSectionHandler, FaibClass.Dynamic"/>   </configSections>   <faibclass.dynamic.webService>     <webservice type="Test.DynamicWebService1" url="http://localhost:1574/WebService/Service.asmx" assemblies="Test.Model, Model" />   </faibclass.dynamic.webService>   <faibclass.data.instance defaultInstance="sqlite">     <!--本地目录下的xml文件-->     <file name="access1">       <instanceType>FaibClass.Data.OleDb, FaibClass.Data2</instanceType>       <filename>{APP}\1.xml</filename>       <path>//config/connection</path>     </file>     <!--系统目录下的xml文件-->     <file name="access2">       <instanceType>FaibClass.Data.OleDb, FaibClass.Data2</instanceType>       <interfaceType>SysXml</interfaceType>       <filename>1.xml</filename>       <path>//config/connection</path>     </file>     <!--本配置文件内-->     <file name="access3">       <instanceType>FaibClass.Data.OleDb, FaibClass.Data2</instanceType>       <interfaceType>AppXml</interfaceType>       <path>constr</path>     </file>     <!--注册表内-->     <reg name="sqlserver">       <instanceType>FaibClass.Data.SqlServer, FaibClass.Data2</instanceType>       <registryKey>CurrentUser</registryKey>       <subKey>Software\Microsoft</subKey>       <key>c</key>     </reg>     <!--二进制文件-->     <file name="sqlserver2005">       <instanceType>FaibClass.Data.SqlServer, FaibClass.Data2</instanceType>       <interfaceType>Binary</interfaceType>       <filename>{APP}\connection.bin</filename>       <path>China</path>     </file>     <!--自定义驱动-->     <string name="sqlite">       <instanceType>FaibClass.Data.DataDriverConverter, FaibClass.Data2</instanceType>       <dataDriver>         <assemblyName>System.Data.SQLite</assemblyName>         <connectionType>System.Data.SQLite.SQLiteConnection</connectionType>         <commandType>System.Data.SQLite.SQLiteCommand</commandType>         <parameterType>System.Data.SQLite.SQLiteParameter</parameterType>         <dataAdapterType>System.Data.SQLite.SQLiteDataAdapter</dataAdapterType>         <parameterPrefix>@</parameterPrefix>       </dataDriver>       <connectionString>Data source={App}BitracDB.db3;Pooling=True</connectionString>     </string>   </faibclass.data.instance>   <appSettings>     <add key="constr" value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source={App}\test.mdb"></add>   </appSettings> </configuration>

 

转载于:https://www.cnblogs.com/yxzhangustcer/archive/2010/04/23/1718763.html

课程通过实际项目融入常用开发技术架构,讲授风格独特,提供详细上课日志及答疑,赠送配套的项目架构源码注释详细清晰且表达通俗,均能直接在实际项目中应用,正真的物超所值,价格实惠任务作业:综合运用《C#/.Net企业级系统架构设计实战精讲教程》课程所学知识技能设计一个学生成绩管理系统的架构。要求:1.系统基于MVC的三层架构,各层单独建不同的解决方案文件夹。2.采用Model First开发方式,设计架构时只需要设计学生表(TbStudent)和课程表(TbCourse)。学生表必须有的字段是ID、stuName、age;课程表必须有的字段是ID、courseName、content。3.数据访问层采用Entity Framework或NHibernate来实现,必须封装对上述表的增删改查方法。4.必须依赖接口编程,也就是必须要有数据访问层的接口层、业务逻辑层的接口层等接口层。层层之间必须减少依赖,可以通过简单工厂或抽象工厂。5.至少采用简单工厂、抽象工厂、Spring.Net等技术中的2种来减少层与层之间的依赖等。6.封装出DbSession类,让它拥有所有Dal层实例和SaveChanges方法。7.设计出数据访问层及业务逻辑层主要类的T4模板,以便实体增加时自动生成相应的类。8.表现层要设计相关的控制器和视图来验证设计的系统架构代码的正确性,必须含有验证增删改查的方法。9.开发平台一定要是Visual Studio平台,采用C#开发语言,数据库为SQL Server。10.提交整个系统架构的源文件及生成的数据库文件。(注意: 作业需写在CSDN博客中,请把作业链接贴在评论区,老师会定期逐个批改~~)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值