依赖注入容器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结尾的类都注册了,语法非常的简单。
时间: 2024-11-03 20:17:18

依赖注入容器Autofac的详解的相关文章

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

依赖注入容器Autofac的详解 发表于 2011 年 09 月 22 日 由 renfengbin 分享到:GMAIL邮箱         Hotmail邮箱 delicious digg Autofac和其他容器的不同之处是它和C#语言的结合非常紧密,在使用过程中对你的应用的侵入性几乎为零,更容易与第三方的组件集成,并且开源,Autofac的主要特性如下: 1,灵活的组件实例化:Autofac支持自动装配,给定的组件类型Autofac自动选择使用构造函数注入或者属性注入,Autofac还可以

依赖注入容器-Autofac

介绍一款依赖注入的容器AutoFac,一直非常迷惑依赖注入到底有独特的优势或者好处,感觉如果用策略模式和反射等也是可以实现这个解耦的,不管怎么样还是先来大概了解依赖注入到底是怎么一回事.              首先来看个例子,如果你想要一把锤子你会怎么做?(这个例子是我百度上看到的,觉得挺形象的) 1.自己造,打铁,锻造等. 2.或者你找制造锤子的工厂订购 3.打开淘宝,下单,支付 上面的例子在程序开发中分别有什么不同:第一种方式显而易见非常麻烦,从开发角度看就是高度耦合,导致使用和制造混在

依赖注入容器Autofac与MVC集成

Autofac是应用于.Net平台的依赖注入(DI,Dependency Injection)容器,具有贴近.契合C#语言的特点.随着应用系统的日益庞大与复杂,使用Autofac容器来管理组件之间的关系可以"扁平化"错综复杂的类依赖,具有很好的适应性和便捷度.  在该篇博文中,我们将应用Autofac,以依赖注入的方式建立传统ASP.NET页面与服务/中间层之间的联系,建立"呈现"与"控制"的纽带. 那么,如何将依赖注入(Dependency I

Spring的控制反转(IOC)和依赖注入(DI)详解

首先介绍下(IOC)控制反转: 所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的.这样控制器就有应用转移到了外部容器,控制权的转移就是反转 示例代码如下: public class PersonServiceBean{ private PersonDao personDao = new <strong><span style="color:#FF0000;">PersonDaoImpl</span></

浅析依赖注入框架Autofac的使用

Autofac是一款IOC框架,比起Spring.NET,Unity,Castle等等框架,它很轻量级且性能也很高,下面小编给大家介绍下依赖注入框架Autofac的使用. 下面通过代码给大家分享下依赖注入框架Autofac的使用,具体如下所示:  Autofac是一款IOC框架,比较于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上也是很高的. 1)解压它的压缩包,主要看到Autofac.dll,Autofac.Configuration.dll,

Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解

原创整理不易,转载请注明出处:Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解 代码下载地址:http://www.zuidaima.com/share/1772661373422592.htm 本文介绍了使用Spring注解注入属性的方法.使用注解以前,注入属性通过类以及配置文件来实现.现在,注入属性可以通过引入@Autowired注解,或者@Resource,@Qualifi

依赖注入之Autofac使用总结

依赖倒置?控制反转(IOC)? 依赖注入(DI)? 你是否还在被这些名词所困扰,是否看了大量理论文章后还是一知半解了? 今天我想结合实际项目,和正在迷惑中的新手朋友一起来学习和总结依赖注入Autofac的使用和理解. 依赖注入粗暴理解 依赖:  public class A { public void A(B b) { // do something } } 这样的代码,估计没有程序猿不曾使用. A类实例化的时候需要一个B的对象作为构造函数的参数,那么A就依赖B,这就叫依赖. 当然,不用构造函数

.Net Core 3.0依赖注入替换 Autofac

今天早上,喜庆的更新VS2019,终于3.0正式版了呀~ 有小伙伴问了一句Autofac怎么接入,因为Startup.ConfigureServices不能再把返回值改成IServiceProvider了,原来的替换依赖注入容器就不可行了,我随口说了一下Host上面.UseServiceProviderFactory 本以为就这么简单,他问我要个例子,自己折腾了一下,发现事情没有这么简单 .UseServiceProviderFactory<TContainer>要搭配Startup里面写一个

如何编写一个简单的依赖注入容器

随着大规模的项目越来越多,许多项目都引入了依赖注入框架,其中最流行的有Castle Windsor, Autofac和Unity Container. 微软在最新版的Asp.Net Core中自带了依赖注入的功能,有兴趣可以查看这里. 关于什么是依赖注入容器网上已经有很多的文章介绍,这里我将重点讲述如何实现一个自己的容器,可以帮助你理解依赖注入的原理. 容器的构想 在编写容器之前,应该先想好这个容器如何使用. 容器允许注册服务和实现类型,允许从服务类型得出服务的实例,它的使用代码应该像 var