• 依赖注入容器Autofac的详解[转]


    依赖注入容器Autofac的详解

    Autofac和其他容器的不同之处是它和C#语言的结合非常紧密,在使用过程中对你的应用的侵入性几乎为零,更容易与第三方的组件集成,并且开源,Autofac的主要特性如下:

    1,灵活的组件实例化:Autofac支持自动装配,给定的组件类型Autofac自动选择使用构造函数注入或者属性注入,Autofac还可以基于lambda表达式创建实例,这使得容器非常灵活,很容易和其他的组件集成。 2,资源管理的可视性:基于依赖注入容器构建的应用程序的动态性,意味着什么时候应该处理那些资源有点困难。Autofac通过容器来跟踪组件的资源管理。对于不需要清理的对象,例如Console.Out,我们调用ExternallyOwned()方法告诉容器不用清理。细粒度的组件生命周期管理:应用程序中通常可以存在一个应用程序范围的容器实例,在应用程序中还存在大量的一个请求的范围的对象,例如一个HTTP请求,一个IIS工作者线程或者用户的会话结束时结束。通过嵌套的容器实例和对象的作用域使得资源的可视化。 3,Autofac的设计上非常务实,这方面更多是为我们这些容器的使用者考虑: ●组件侵入性为零:组件不需要去引用Autofac。 ●灵活的模块化系统:通过模块化组织你的程序,应用程序不用纠缠于复杂的XML配置系统或者是配置参数。 ●自动装配:可以是用lambda表达式注册你的组件,autofac会根据需要选择构造函数或者属性注入 ●XML配置文件的支持:XML配置文件过度使用时很丑陋,但是在发布的时候通常非常有用

    Autofac的简单使用,并加入了Repository模式.

    定义两个简单实体类:
    public class Persion
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
    
    public class Custom
    {
        public string CustomName { get; set; }
        public int CustomID { get; set; }
    }
    定义泛型数据库访问接口:
    public interface Idal<T> where T:class
    {
        void Insert(T entity);
        void Update(T entity);
        void Delete(T entity);
    }
    泛型数据库访问接口的泛型实现:
    public class Dal<T>:Idal<T> where T : class
    {
    
        #region Idal<T> Members
    
        public void Insert(T entity)
        {
            HttpContext.Current.Response.Write("您添加了一个:"
               +entity.GetType().FullName);
        }
    
        public void Update(T entity)
        {
    
            HttpContext.Current.Response.Write("您更新一个:"
                 +entity.GetType().FullName);
        }
    
        public void Delete(T entity)
        {
            HttpContext.Current.Response.Write("您删除了一个:"
                  +entity.GetType().FullName);
        }
    
        #endregion
    }

    使用Repository模式实现访问。

    //Repository的泛型接口:
    public interface IRepository<T> where T:class
    {
        void Insert(T entity);
        void Update(T entity);
        void Delete(T entity);
    }
    
    
     
    //Repository泛型接口的泛型实现:
    public class Repository<T>:IRepository<T> where T:class
    {
        private Idal<T> _dal;
        public Repository(Idal<T> dal)
        {
            _dal = dal;
        }
    
        #region IRepository<T> Members
    
        public void Insert(T entity)
        {
            _dal.Insert(entity);
        }
    
        public void Update(T entity)
        {
            _dal.Update(entity);
        }
    
        public void Delete(T entity)
        {
            _dal.Delete(entity);
        }
    
        #endregion
    }
    IDependency的依赖接口,不需要任何方法体,所有的业务对象都实现该接口
    public interface IDependency
    {
    }
    实现IDependency接口的CustomBll类,通过Repository模式存储数据。
    public class CustomBll:IDependency
    {
        private readonly IRepository<Custom> _repository;
        public CustomBll(IRepository<Custom> repository)
        {
            _repository = repository;
        }
    
        public void Insert(Custom c)
        {
            _repository.Insert(c);
        }
    
        public void Update(Custom c)
        {
            _repository.Update(c);
        }
    
        public void Delete(Custom c)
        {
            _repository.Delete(c);
        }
    }
    实现IDependency接口的PersionBll类,通过Repository模式存储数据。
    public class PersionBll:IDependency
    {
        private readonly IRepository<Persion> _repository;
        public PersionBll(IRepository<Persion> repository)
        {
            _repository = repository;
        }
    
        public void Insert(Persion p)
        {
            _repository.Insert(p);
        }
    
        public void Update(Persion p)
        {
            _repository.Update(p);
        }
    
        public void Delete(Persion p)
        {
            _repository.Delete(p);
        }
    }

    下面编写组件实例化测试

    var builder = new ContainerBuilder();
    builder.RegisterGeneric(typeof(Dal<>)).As(typeof(Idal<>))
        .InstancePerDependency();
    builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>))
        .InstancePerDependency();
    builder.Register(c=>new PersionBll((IRepository<Persion>)
        c.Resolve(typeof(IRepository<Persion>))));
    builder.Register(c => new CustomBll((IRepository<Custom>)
        c.Resolve(typeof(IRepository<Custom>))));
    
    //var container = builder.Build()教程里都是使用这行代码,
    //我本地测试需要加入ContainerBuildOptions枚举选项。
    using (var container = builder.Build(ContainerBuildOptions.None))  
    {
    
        // var repository= container.Resolve(typeof(IRepository<Persion>),new TypedParameter());
        // IRepository<Persion> _repository = repository as Repository<Persion>;
        // var m = new PersionBll(_repository);
        Persion p = new Persion();
        p.Name = "小人";
        p.Age = 27;
        var m = container.Resolve<PersionBll>();
        m.Insert(p);
        Custom c = new Custom();
        c.CustomName = "小小";
        c.CustomID = 10;
        var cc = container.Resolve<CustomBll>();
        cc.Update(c);
    }

    这里通过ContainerBuilder方法RegisterGeneric对泛型类进行注册(当然也可以通过ContainerBuilder方法RegisterType对不是泛型的类进行注册),当注册的类型在相应得到的容器中可以Resolve你的类实例。 builder.RegisterGeneric(typeof(Dal<>)).As(typeof(Idal<>)).InstancePerDependency();通过AS可以让类中通过构造函数依赖注入类型相应的接口。(当然也可以使用builder.RegisterType<类>().As<接口>();来注册不是泛型的类 ) Build()方法生成一个对应的Container实例,这样,就可以通过Resolve解析到注册的类型实例。

    注:如果要获得某个泛型的实例,需要将泛型T代表的类传进去。如上c.Resolve(typeof(IRepository<Persion>))返回的是Object,需要转换为响应的接口。

    当然可以使用autofac的新特性RegisterAssemblyTypes,从一个程序集的注册类型设置根据用户指定的规则,例子如下:

    var builder = new ContainerBuilder();
    builder.RegisterGeneric(typeof(Dal<>)).As(typeof(Idal<>)).InstancePerDependency();
    builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerDependency();
    //上面的那些类如果在单独的工程里,如生成的程序集为AutofacUnitTest,就可以使用
    //Assembly.Load("AutofacUnitTest")获得响应的程序集。如果所有的文件在一个控制台程序里,
    //可以通过Assembly.GetExecutingAssembly(); 直接获得相应的程序集。
    Assembly dataAccess = Assembly.Load("AutofacUnitTest"); 
    builder.RegisterAssemblyTypes(dataAccess)
            .Where(t => typeof(IDependency).IsAssignableFrom(t) && t.Name.EndsWith("Bll"));
    //RegisterAssemblyTypes方法将实现IDependency接口并已Bll结尾的类都注册了,语法非常的简单。
    此条目发表在 开源 分类目录。将固定链接加入收藏夹。
  • 相关阅读:
    2015总结篇
    Android应用性能优化实践
    Android国外学习资源汇总
    直接拿来用!十大Material Design开源项目
    selenium12-读取文件 excel
    selenium11-自动化练习读取文件txt
    selenium10-python3部分代码复习
    selenium09-自动化练习案例
    selenium08-测试用例模块化与数据分离
    selenium07-处理 alter 对话框
  • 原文地址:https://www.cnblogs.com/shengfa/p/4022893.html
Copyright © 2020-2023  润新知