Spring.NET的IOC容器解决的,就是如何在应用中将类、对象和服务组合成应用程序的问题。IOC容器通过很正统的方式将分散的组件组合成完整的应用程序。Spring.NET框架就应运而生了。
框架图:
其中Spring.NET Core是整个矿机阿德基础,实现了依赖注入的功能。Spring.AOP为业务对象提供面向切面编程的支持。Spring.WEB提供了客户端。Spring.Services允许将服务发布为企业服务或远程服务(WCF)。Spring.Data定义了一个抽象的数据访问层,可以跨越各种数据访问技术进行数据访问。Spring.ORM包含生命是事物管理等功能。
在ITOO中我们最终实现的AOP是这样的:
U层调用业务层,业务层调用AOP,这一步使用的AOP中拦截的思想,用特性标签进行实现的,AOP调用Service层,使用的是代理和容器,将远程的服务全部配置在配置文件中,应用代理,运行WCF提供的服务。
实现代码:
AOP项目中:
首先写拦截特性类:COntrollerAttribute类:
<span style="font-size:18px;">using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; using System.Web; namespace AOP { [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] public sealed class ControllerAttribute : Attribute, IOperationBehavior { void IOperationBehavior.AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { } void IOperationBehavior.ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { } void IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) { dispatchOperation.Invoker = new ControllerInvoker(dispatchOperation.Invoker); } void IOperationBehavior.Validate(OperationDescription operationDescription) { } } }</span>
写ControllerInvoker类:
<span style="font-size:18px;">using ITOO.UINonQueryProperties.Contracts; using Spring.Context; using Spring.Context.Support; using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.ServiceModel.Dispatcher; using System.Web; namespace AOP { internal sealed class ControllerInvoker : IOperationInvoker { private readonly IOperationInvoker Inner; public ControllerInvoker(IOperationInvoker inner) { Inner = inner; } public object[] AllocateInputs() { return Inner.AllocateInputs(); } public object Invoke(object instance, object[] inputs, out object[] outputs) { // do something before invoking //Console.WriteLine("12354566778"); object result =Inner.Invoke(instance, inputs, out outputs); IApplicationContext ctx = ContextRegistry.GetContext(); try { //foreach (IAdd proxy in ctx.GetObjectsOfType(typeof(IAdd)).Values) //{ // Console.WriteLine(string.Format("invocation result is :{0}", proxy.Add(1, 2))); // (proxy as ICommunicationObject ).Close(); //} // IUINonQueryPropertiesService proxy0 = ctx.GetObject("WsHttpBinding_Services") as IUINonQueryPropertiesService; //应用代理模式提供服务的 Console.WriteLine(string.Format("invocation result is :{0}", proxy0.GetOneQueryPropertie("123"))); (proxy0 as ICommunicationObject).Close(); } catch (Exception ex) { Console.WriteLine(ex.StackTrace); throw; } // do something after invoking return result; } public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state) { throw new NotSupportedException(); } public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result) { throw new NotSupportedException(); } public bool IsSynchronous { get { return true; } } } }</span>
我们配置XML文件,在该文件中进行配置WCF服务:
<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8" ?> <objects xmlns="http://www.springframework.net" xmlns:wcf="http://www.springframework.net/wcf"> <!--<wcf:channelFactory channelType="Contracts.IAdd,Contracts" endpointConfigurationName="addService" id="addService"> </wcf:channelFactory>--> <wcf:channelFactory channelType="ITOO.UINonQueryProperties.Contracts.IUINonQueryPropertiesService,ITOO.UINonQueryProperties.Contracts" endpointConfigurationName="WsHttpBinding_Services" id="WsHttpBinding_Services"> </wcf:channelFactory> </objects></span>
在App.config中读取上面的XML文件:
<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections > <sectionGroup name="spring"> <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/> <section name="objects" type="Spring.Context.Support.DefaultSectionHandler,Spring.Core"/> </sectionGroup> </configSections> <spring> <context> <resource uri="assembly://AOP/AOP.Config/WCFServiceConfig.xml"></resource> </context> </spring> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name=""> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> <bindings> <wsHttpBinding> <binding name="WsHttpBinding_Default" transactionFlow="true" > <security mode="None"> <transport clientCredentialType="None" proxyCredentialType="None" realm=""/> <message clientCredentialType="UserName" algorithmSuite="Default"/> </security> </binding> </wsHttpBinding> </bindings> <!--<client> <endpoint address="http://127.0.0.1:6633/AddService" binding="basicHttpBinding" contract="Contracts.IAdd" name="addService"></endpoint> </client>--> <client> <!--资源服务--> <!--<endpoint address="http://localhost:9914/Service.svc?wsdl" binding="wsHttpBinding" bindingConfiguration="WsHttpBinding_Default" contract="ITOO.UINonQueryProperties.Contracts.IUINonQueryPropertiesService" name="WsHttpBinding_Services"/>--> <!--<endpoint address="http://localhost:9914/Service.svc?wsdl" binding="wsHttpBinding" contract="ITOO.UINonQueryProperties.Contracts.IUINonQueryPropertiesService" name="UINonQueryPropertiesService"/>--> <endpoint address="http://localhost:9914/Service.svc?wsdl" binding="wsHttpBinding" bindingConfiguration="WsHttpBinding_Default" contract="ITOO.UINonQueryProperties.Contracts.IUINonQueryPropertiesService" name="WsHttpBinding_Services"/> </client> </system.serviceModel> </configuration></span>
进行测试:
<span style="font-size:18px;">using ITOO.BasicStudent.Contracts; using ITOO.BasicStudent.ViewModel; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace AOPTest { class Program { static void Main(string[] args) { IBasicStudentService studentService = ServiceStudentFactory.GetStudentInfosService(); List<StudentViewModel> stuclassList = new List<StudentViewModel>(); StudentViewModel stuclass = new StudentViewModel(); studentService.AddOneStudent(stuclass); } } } </span>
这里我们想要在AddOneStudent中加上服务,那么我们看到在客户端我们只需要在调用AddOneStudent的服务就可以了,具体在切面上有什么服务,我们直接在AOP项目的COntrollerInvoker中写就可以了。
我们想要在AddOneStudent方法上面家服务,就必须要拦截该方法,如果是MVC就可以使用Filter,如果是WCF我们就可以使用特性,一般普通的类都可以使用特性来进行拦截。
因为AddOneStudent为我们的业务,但是,实际上它也是一种WCF提供的远程服务,这个时候,我们就可以在Constract层中的这个方法上加上特性标签。
具体如下:
<span style="font-size:18px;"> /// <summary> /// 添加单个学生 /// </summary> /// <param name="student">单个学生实体</param> /// <returns>bool</returns> [Controller] [OperationContract] void AddOneStudent(StudentViewModel student);</span>
这样就可以将该业务进行拦截了,要是改方法不是WCF服务,我们就可以直接在该方法的上面加上特性标签了。
总结:
其实,很多上面说到的一些东西,我并不是特别了解,很多都是人家已经写好资料,拿过来用的,知识在于理解,在于整理,在于积累,在于编织。