zoukankan      html  css  js  c++  java
  • Autofac的简单使用

    有关依赖注入的原理这里就不说了,依赖注入的框架比较多,比如:Castle、Unity、Ninject、Autofac、StructureMap、Spring.Net等。最近在项目中使用了Autofac,借此机会进行一些总结,也顺便跟大家讨论一下。Autofac主要用了Autofac.dll,AutoMapper.dll。

    举个简单的例子,有一个应用用的数据库是Sql Server,将来不排除要使用Oracle或者是其它数据库。那么我们在开发的时候就要考虑了,将来要换数据库的时候是不是要重新开发?一般我们的做法是,将跟数据库交互的放在接口里,然后用Sql Server、Oracle的相关类去实现该接口,在程序初始化的时候根据数据库去实例化相应的接口。直接贴上代码:

    IDatabase接口

    public interface IDatabase
        {
            string Name { get; }
    
            void Select(string commandText);
    
            void Insert(string commandText);
    
            void Update(string commandText);
    
            void Delete(string commandText);
        }
    View Code

    SqlDatabase类

    public class SqlDatabase : IDatabase
        {
            public string Name
            {
                get { return "sqlserver"; }
            }
    
            public void Select(string commandText)
            {
                Console.WriteLine(string.Format("'{0}' is a query sql in {1}!", commandText, Name));
            }
    
            public void Insert(string commandText)
            {
                Console.WriteLine(string.Format("'{0}' is a insert sql in {1}!", commandText, Name));
            }
    
            public void Update(string commandText)
            {
                Console.WriteLine(string.Format("'{0}' is a update sql in {1}!", commandText, Name));
            }
    
            public void Delete(string commandText)
            {
                Console.WriteLine(string.Format("'{0}' is a delete sql in {1}!", commandText, Name));
            }
        }
    View Code

    OracleDatabase类

    public class OracleDatabase : IDatabase
        {
            public string Name
            {
                get { return "oracle"; }
            }
    
            public void Select(string commandText)
            {
                Console.WriteLine(string.Format("'{0}' is a query sql in {1}!", commandText, Name));
            }
    
            public void Insert(string commandText)
            {
                Console.WriteLine(string.Format("'{0}' is a insert sql in {1}!", commandText, Name));
            }
    
            public void Update(string commandText)
            {
                Console.WriteLine(string.Format("'{0}' is a update sql in {1}!", commandText, Name));
            }
    
            public void Delete(string commandText)
            {
                Console.WriteLine(string.Format("'{0}' is a delete sql in {1}!", commandText, Name));
            }
        }
    View Code

    在这里,还新增了DataBase的管理类,避免客户端直接操作IDatabase的实现类。

    public class DatabaseManager
        {
            IDatabase _database;
    
            public DatabaseManager(IDatabase database)
            {
                _database = database;
            }
    
            public void Search(string commandText)
            {
                _database.Select(commandText);
            }
    
            public void Add(string commandText)
            {
                _database.Insert(commandText);
            }
    
            public void Save(string commandText)
            {
                _database.Update(commandText);
            }
    
            public void Remove(string commandText)
            {
                _database.Delete(commandText);
            }
        }
    View Code

    下面,我们来看Autofac的使用:

    var builder = new ContainerBuilder();
                builder.RegisterType<DatabaseManager>();
                //builder.RegisterType<SqlDatabase>().As<IDatabase>();
                builder.RegisterType<OracleDatabase>().As<IDatabase>();
                using (var container = builder.Build())
                {
                    var manager = container.Resolve<DatabaseManager>();
                    manager.Search("SELECT * FORM USER");
                }
    View Code

    如果要用Sql Server数据库,则将builder.RegisterType<OracleDatabase>().As<IDatabase>()改为builder.RegisterType<SqlDatabase>().As<IDatabase>()即可,其它都不变。

    不过,有人会问,我直接new一个对象不是更简单么?确实,如果只有一个实现类,用new可能会更简单。但是,一个应用通常会有很多的实现类,如果都用new的话,无疑增加了维护的困难。

    我不修改代码可以吗?答案是可以的。你可以通过配置文件来配置,下面增加一个配置:

    <configSections>
        <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/>
      </configSections>
      <autofac defaultAssembly="AutofacDemo">
        <components>
          <component type="AutofacDemo.SqlDatabase, AutofacDemo" service="AutofacDemo.IDatabase"/>
        </components>
      </autofac>
    View Code

    客户端实现的代码如下:

    var builder = new ContainerBuilder();
                builder.RegisterType<DatabaseManager>();
                builder.RegisterModule(new ConfigurationSettingsReader("autofac"));
                using (var container = builder.Build())
                {
                    var manager = container.Resolve<DatabaseManager>();
                    manager.Search("SELECT * FORM USER");
                }
    View Code

    同样可以得到相同的结果。

    这只是Autofac的简单使用。一个应用会有成千上万个实现类,如果每次使用时都是先注册再获取实现类的话,那用依赖注入就没多大意义了。其实,我们可以做一个公共组件,在程序初始化的时候注册,需要用的时候再获取出来,这样就很方便了。

    程序初始化时调用EngineContext.Initialize(false)即可,接下来就可以直接像EngineContext.Current.Resolve<IDatabase>()这样使用了。

    https://files.cnblogs.com/files/dengwenbo/AutofacInfrastructure.rar

  • 相关阅读:
    10 shell test命令
    9 shell 退出状态
    8 shell if else
    7 shell 数学运算
    6-x3 declare和typeset命令:设置变量属性
    6-x1 read命令:从键盘读取数据
    Bootstrap 有一个 class 属性叫做 well,它的作用是为设定的列创造出一种视觉上的深度感
    form-control给input添加这个class类后就会使用bootstrap自带的input框
    bootstrap文字居中!
    img-responsive class图片响应式
  • 原文地址:https://www.cnblogs.com/dengwenbo/p/4716582.html
Copyright © 2011-2022 走看看