VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Python基础教程 >
  • python基础教程之C# Autofac学习笔记(2)

本站最新发布   Python从入门到精通|Python基础教程
试听地址  
https://www.xin3721.com/eschool/pythonxin3721/


(List<>)).As(typeof(IList<>)); IContainer container = builder.Build(); IList<string> list = container.Resolve<IList<string>>();

    3.6、默认注册

复制代码
            ContainerBuilder builder = new ContainerBuilder();
            //对于同一个接口,后面注册的实现会覆盖之前的实现。

            //如果不想覆盖的话,可以用PreserveExistingDefaults,这样会保留原来注册的实现。
            builder.RegisterType<Dog>().As<IAnimalSleep>();
            builder.RegisterType<Cat>().As<IAnimalSleep>().PreserveExistingDefaults();  //指定为非默认值
            IContainer container = builder.Build();

            var dog = container.Resolve<IAnimalSleep>();
            dog.Sleep();
复制代码

    四、IoC-注入

    4.1、构造函数注入

复制代码
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterType<AnimalWagging>();
            builder.RegisterType<Dog>().As<IAnimalBark>();
            IContainer container = builder.Build();

            AnimalWagging animal = container.Resolve<AnimalWagging>();
            animal.Wagging();
复制代码

    4.2、属性注入

复制代码
            ContainerBuilder builder = new ContainerBuilder();
            Assembly assembly = Assembly.Load("LinkTo.Test.Autofac.Service");                           //实现类所在的程序集名称
            builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces().PropertiesAutowired();    //常用
            IContainer container = builder.Build();

            ISchool school = container.Resolve<ISchool>();
            school.LeaveSchool();
复制代码

    五、IoC-事件

    Autofac在组件生命周期的不同阶段,共对应了5个事件,执行顺序如下所示:

    1.OnRegistered->2.OnPreparing->3.OnActivating->4.OnActivated->5.OnRelease

复制代码
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterType<Student>().As<IStudent>()
                .OnRegistered(e => Console.WriteLine("OnRegistered:在注册的时候调用"))
                .OnPreparing(e => Console.WriteLine("OnPreparing:在准备创建的时候调用"))
                .OnActivating(e => Console.WriteLine("OnActivating:在创建之前调用"))
                //.OnActivating(e => e.ReplaceInstance(new Student("1000", "Test")))
                .OnActivated(e => Console.WriteLine("OnActivated:在创建之后调用"))
                .OnRelease(e => Console.WriteLine("OnRelease:在释放占用的资源之前调用"));
            using (IContainer container = builder.Build())
            {
                IStudent student = container.Resolve<IStudent>();
                student.Add("1001", "Hello");
            }
复制代码

    六、IoC-生命周期

    6.1、Per Dependency

    Per Dependency:为默认的生命周期,也被称为"transient"或"factory",其实就是每次请求都创建一个新的对象。

复制代码
            ContainerBuilder builder = new ContainerBuilder();
            Assembly assembly = Assembly.Load("LinkTo.Test.Autofac.Service");                                                   //实现类所在的程序集名称
            builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces().PropertiesAutowired().InstancePerDependency();    //常用
            IContainer container = builder.Build();

            ISchool school1 = container.Resolve<ISchool>();
            ISchool school2 = container.Resolve<ISchool>();
            Console.WriteLine(school1.Equals(school2));
复制代码

    6.2、Single Instance

    Single Instance:就是每次都用同一个对象。

复制代码
            ContainerBuilder builder = new ContainerBuilder();
            Assembly assembly = Assembly.Load("LinkTo.Test.Autofac.Service");                                           //实现类所在的程序集名称
            builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces().PropertiesAutowired().SingleInstance();   //常用
            IContainer container = builder.Build();

            ISchool school1 = container.Resolve<ISchool>();
            ISchool school2 = container.Resolve<ISchool>();
            Console.WriteLine(ReferenceEquals(school1, school2));
复制代码

    6.3、Per Lifetime Scope

    Per Lifetime Scope:同一个Lifetime生成的对象是同一个实例。

复制代码
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterType<School>().As<ISchool>().InstancePerLifetimeScope();
            IContainer container = builder.Build();
            ISchool school1 = container.Resolve<ISchool>();
            ISchool school2 = container.Resolve<ISchool>();
            Console.WriteLine(school1.Equals(school2));
            using (ILifetimeScope lifetime = container.BeginLifetimeScope())
            {
                ISchool school3 = lifetime.Resolve<ISchool>();
                ISchool school4 = lifetime.Resolve<ISchool>();
                Console.WriteLine(school3.Equals(school4));
                Console.WriteLine(school2.Equals(school3));
            }
复制代码

    七、IoC-通过配置文件使用Autofac

    7.1、组件安装

    Client项目右键->管理 NuGet 程序包->Autofac.Configuration及Microsoft.Extensions.Configuration.Xml。

    7.2、配置文件

    新建一个AutofacConfigIoC.xml文件,在其属性的复制到输出目录项下选择始终复制。

复制代码
<?xml version="1.0" encoding="utf-8" ?>
<autofac defaultAssembly="LinkTo.Test.Autofac.IService">
  <!--无注入-->
  <components name="1001">
    <type>LinkTo.Test.Autofac.Service.Student, LinkTo.Test.Autofac.Service</type>
    <services name="0" type="LinkTo.Test.Autofac.IService.IStudent" />
    <injectProperties>true</injectProperties>
  </components>
  <components name="1002">
    <type>LinkTo.Test.Autofac.Service.Dog, LinkTo.Test.Autofac.Service</type>
    <services name="0" type="LinkTo.Test.Autofac.IService.IAnimalBark" />
    <injectProperties>true</injectProperties>
  </components>
  <!--构造函数注入-->
  <components name="2001">
    <type>LinkTo.Test.Autofac.Service.AnimalWagging, LinkTo.Test.Autofac.Service</type>
    <services name="0" type="LinkTo.Test.Autofac.Service.AnimalWagging, LinkTo.Test.Autofac.Service" />
    <injectProperties>true</injectProperties>
  </components>
  <!--属性注入-->
  <components name="3001">
    <type>LinkTo.Test.Autofac.Service.School, LinkTo.Test.Autofac.Service</type>
    <services name="0" type="LinkTo.Test.Autofac.IService.ISchool" />
    <injectProperties>true</injectProperties>
  </components>
</autofac>
复制代码

    7.3、测试代码

复制代码
            //加载配置
            ContainerBuilder builder = new ContainerBuilder();
            var config = new ConfigurationBuilder();
            config.AddXmlFile("AutofacConfigIoC.xml");
            var module = new ConfigurationModule(config.Build());
            builder.RegisterModule(module);
            IContainer container = builder.Build();
            //无注入测试
            IStudent student = container.Resolve<IStudent>();
            student.Add("1002", "World");
            //构造函数注入测试
            AnimalWagging animal = container.Resolve<AnimalWagging>();
            animal.Wagging();
            //属性注入测试
            ISchool school = container.Resolve<ISchool>();
            school.LeaveSchool();
复制代码

    八、AOP 

    8.1、组件安装

    Client项目右键->管理 NuGet 程序包->Autofac.Extras.DynamicProxy。

    8.2、拉截器

复制代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Castle.DynamicProxy;

namespace LinkTo.Test.Autofac.Client
{
    /// <summary>
    /// 拦截器:需实现IInterceptor接口。

    /// </summary>
    public class CallLogger : IInterceptor
    {
        private readonly TextWriter _output;

        public CallLogger(TextWriter output)
        {
            _output = output;
        }

        /// <summary>
        /// 拦截方法:打印被拦截的方法--执行前的名称、参数以及执行后的返回结果。

        /// </summary>
        /// <param name="invocation">被拦截方法的信息</param>
        public void Intercept(IInvocation invocation)
        {
            //空白行
            _output.WriteLine();

            //在下一个拦截器或目标方法处理之前的处理
            _output.WriteLine($"调用方法:{invocation.Method.Name}");

            if (invocation.Arguments.Length > 0)
            {
                _output.WriteLine($"参数:{string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray())}");
            }

            //调用下一个拦截器(若存在),直到最终的目标方法(Target Method)。
            invocation.Proceed();

            //获取被代理方法的返回类型
            var returnType = invocation.Method.ReturnType;

            //异步方法
            if (IsAsyncMethod(invocation.Method))
            {
                //Task:返回值是固定类型
                if (returnType != null && returnType == typeof(Task))
                {
                    //定义一个异步方法来等待目标方法返回的Task
                    async Task Continuation() => await (Task)invocation.ReturnValue;
                    //Continuation()中并没有使用await,所以Continuation()就如同步方法一样是阻塞的。
                    invocation.ReturnValue = Continuation();
                }
                //Task<T>:返回值是泛型类型
                else
                {
                    //获取被代理方法的返回类型
                    var returnTypeT = invocation.Method.ReflectedType;
                    if (returnTypeT != null)
                    {
                        //获取泛型参数集合,集合中的第一个元素等价于typeof(Class)。
                        var resultType = invocation.Method.ReturnType.GetGenericArguments()[0];
                        //利用反射获得等待返回值的异步方法
                        MethodInfo methodInfo = typeof(CallLogger).GetMethod("HandleAsync", BindingFlags.Public | BindingFlags.Instance);
                        //调用methodInfo类的MakeGenericMethod()方法,用获得的类型T(<resultType>)来重新构造HandleAsync()方法。
                        var mi = methodInfo.MakeGenericMethod(resultType);
                        //Invoke:使用指定参数调用由当前实例表示的方法或构造函数。
                        invocation.ReturnValue = mi.Invoke(this, new[] { invocation.ReturnValue });
                    }
                }

                var type = invocation.Method.ReturnType;
                var resultProperty = type.GetProperty("Result");

                if (resultProperty != null)
                    _output.WriteLine($"方法结果:{resultProperty.GetValue(invocation.ReturnValue)}");
            }
            //同步方法
            else
            {
                if (returnType != null && returnType != typeof(void))
                    _output.WriteLine($"方法结果:{invocation.ReturnValue}");
            }
        }

        /// <summary>
        /// 判断是否异步方法
        /// </summary>
        public static bool IsAsyncMethod(MethodInfo method)
        {
            return 
                (
                    method.ReturnType == typeof(Task) || 
                    (method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>))
                );
        }

        /// <summary>
        /// 构造等待返回值的异步方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="task"></param>
        /// <returns></returns>
        public async Task<T> HandleAsync<T>(Task<T> task)
        {
            var t = await task;
            return t;
        }
    }
}
复制代码
复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Castle.DynamicProxy;

namespace LinkTo.Test.Autofac.Client
{
    public class CallTester: IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            Console.WriteLine("啥也不干");
            invocation.Proceed();
            Console.WriteLine("也不干啥");
        }
    }
}
复制代码

    8.3、测试代码

    注意:对于以类方式的注入,Autofac Interceptor要求类的方法必须为virtual方法。如AnimalWagging类的Wagging()、WaggingAsync(string name)都加了virtual修饰符。

复制代码
            ContainerBuilder builder = new ContainerBuilder();

            //注册拦截器
            builder.Register(c => new CallLogger(Console.Out));
            builder.Register(c => new CallTester());

            //动态注入拦截器

            //这里定义了两个拦截器,注意它们的顺序。
            builder.RegisterType<Student>().As<IStudent>().InterceptedBy(typeof(CallLogger), typeof(CallTester)).EnableInterfaceInterceptors();

            //这里定义了一个拦截器
            builder.RegisterType<AnimalWagging>().InterceptedBy(typeof(CallLogger)).EnableClassInterceptors();
            builder.RegisterType<Dog>().As<IAnimalBark>();

            IContainer container = builder.Build();
            IStudent student = container.Resolve<IStudent>();
            student.Add("1003", "Kobe");

            AnimalWagging animal = container.Resolve<AnimalWagging>();
            animal.Wagging();

            Task<string> task = animal.WaggingAsync("哈士奇");
            Console.WriteLine($"{task.Result}");
复制代码

相关教程
        
关于我们--广告服务--免责声明--本站帮助-友情链接--版权声明--联系我们       黑ICP备07002182号