使用Autofac做ioc

一.目前流行的ioc框架:

  1. Unity:微软patterns&practicest团队开发的IOC依赖注入框架,支持AOP横切关注点。(下篇文章会写)
  2. MEF(Managed Extensibility Framework):是一个用来扩展.NET应用程序的框架,可开发插件系统。MEF(Managed
    Extensibility Framework):是一个用来扩展.NET应用程序的框架,可开发插件系统。Extensibility Framework):是一个用来扩展.NET应用程序的框架,可开发插件系统。
  3. Spring.NET:依赖注入、面向方面编程(AOP)、数据访问抽象,、以及ASP.NET集成。Spring.NET:依赖注入、面向方面编程(AOP)、数据访问抽象,、以及ASP.NET集成。
  4. PostSharp:实现静态AOP横切关注点,使用简单,功能强大,对目标拦截的方法无需任何改动。PostSharp:实现静态AOP横切关注点,使用简单,功能强大,对目标拦截的方法无需任何改动。(收费)
  5. Autofac是.NET领域最为流行的IOC框架之一

1.1 Autofac特性介绍:

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

二:例子

首先引用Dll: Autofac
在这里插入图片描述

1.定义一个类

public class Persion
{
    public string Name { get; set; }
    public int Age { get; set; }
}
2.定义一个可以操作数据的接口泛型,以及具体实现
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
}
3.定义仓储模式,及其实现,具体实现的仓储中,构造函数Idal注入
public interface IRepository<T> where T:class
{
    void Insert(T entity);
    void Update(T entity);
    void Delete(T entity);
}


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
}
4.IDependency的依赖接口,不需要任何方法体,所有的业务对象都实现该接口
public interface IDependency
{
}
5.实现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);
    }
}
6.声明容器调用方法
 static void Main(string[] args)
        {
            try
            {
/// 定义容器,在容器里面注入类型
                var builder = new ContainerBuilder();
                builder.RegisterGeneric(typeof(Dal<>)).As(typeof(Idal<>))
                   .InstancePerDependency();
                builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>))
                    .InstancePerDependency();
                //    在Autofac中,我们使用一个ContainerBuilder类的实例来注册我们的我们的组件. Autofac提供了Register方法家族,方便我们注册组件.
                builder.Register(c => new PersionBll((IRepository<Persion>)
                    c.Resolve(typeof(IRepository<Persion>))));  //直接将类注册进去,Resolve去实例
                    
                //var container = builder.Build()教程里都是使用这行代码,
                //我本地测试需要加入ContainerBuildOptions枚举选项。
                //创建一个Container以备后用.直接调用ContainerBuilder类实例的build()即可.
                using (var container = builder.Build(ContainerBuildOptions.None))
                {
                 
                    Persion p = new Persion();
                    p.Name = "小人";
                    p.Age = 27;
                    var m = container.Resolve<PersionBll>();
                    m.Insert(p);
                }

                Console.WriteLine();

                Console.ReadLine();
            }
            catch (Exception ex)
            {
                
                throw ex;
            }
        }

注:这里通过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))返回的是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结尾的类都注册了,语法非常的简单。

还有一种注册方式,
1.在Global.asax文件中添加:

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            var builder = RegisterAll();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }

        public ContainerBuilder RegisterAll()
        {
        //扫描所有dll,然后为实现IDependency接口的类,进行IOC注册,当然还有其他注册方式,我觉得这是一种简单的注册方式。
            var builder = new ContainerBuilder();
            Assembly[] assemblies = Directory.GetFiles(AppDomain.CurrentDomain.RelativeSearchPath, "*.dll").Select(Assembly.LoadFrom).ToArray();
            Type baseType = typeof(IDependency);
            builder.RegisterAssemblyTypes(assemblies)
            .Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract)
            .AsSelf().AsImplementedInterfaces()
            .PropertiesAutowired().InstancePerLifetimeScope();
            builder.RegisterControllers(assemblies).PropertiesAutowired();
            return builder;
        }

2.注入方式:
默认支持构造函数注入。
属性注入需要在注册组件是加入PropertiesAutowired()方法即可。


使用了IoC之后,就符合设计模式中要求的"针对接口编程,不针对实现编程";创建实例不是使用New关键字创建,而是创建实例的工作交给了IoC容器,这就实现了关系解耦,可以在IoC容器中随便的替换具体的实现类了.

参考文档:
http://www.bkjia.com/C_jc/888110.html
https://www.cnblogs.com/zjoch/p/6485170.html
https://www.cnblogs.com/hnsongbiao/p/4805343.html
https://blog.csdn.net/f627422467/article/details/53065017

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值