zoukankan      html  css  js  c++  java
  • 依赖注入框架Autofac的简单使用

          Autofac是一款IOC框架,比较于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上也是很高的。于是,今天抽空研究了下它。下载地址:http://code.google.com/p/autofac/downloads/list

    1)解压它的压缩包,主要看到Autofac.dll,Autofac.Configuration.dll,这也是本篇文章重点使用的Autofac的类库。

    2)创建一个控制台工程,并且引用以上的DLL文件。创建一个数据库操作接口IDatabase.cs:

    复制代码
    ///<summary>/// Database operate interface ///</summary>publicinterface IDatabase { string Name { get; }
    void Select(string commandText);
    void Insert(string commandText);
    void Update(string commandText);
    void Delete(string commandText); }
    复制代码

    这里包含CRUD四种操作的方法。

    3)创建两种数据库的操作类,SqlDatabase.cs以及OracleDatabase.cs:

    复制代码
    publicclass SqlDatabase : IDatabase {     publicstring Name     {         get { return"sqlserver"; }     }
       
    publicvoid Select(string commandText)     {         Console.WriteLine(string.Format("'{0}' is a query sql in {1}!", commandText, Name));     }
       
    publicvoid Insert(string commandText)     {         Console.WriteLine(string.Format("'{0}' is a insert sql in {1}!", commandText, Name));     }
       
    publicvoid Update(string commandText)     {         Console.WriteLine(string.Format("'{0}' is a update sql in {1}!", commandText, Name));     }
       
    publicvoid Delete(string commandText)     {         Console.WriteLine(string.Format("'{0}' is a delete sql in {1}!", commandText, Name));     } }
    复制代码

    以及

    复制代码
    publicclass OracleDatabase : IDatabase {     publicstring Name     {         get { return"oracle"; }     }
       
    publicvoid Select(string commandText)     {         Console.WriteLine(string.Format("'{0}' is a query sql in {1}!", commandText, Name));     }
       
    publicvoid Insert(string commandText)     {         Console.WriteLine(string.Format("'{0}' is a insert sql in {1}!", commandText, Name));     }
       
    publicvoid Update(string commandText)     {         Console.WriteLine(string.Format("'{0}' is a update sql in {1}!", commandText, Name));     }
       
    publicvoid Delete(string commandText)     {         Console.WriteLine(string.Format("'{0}' is a delete sql in {1}!", commandText, Name));     } }
    复制代码

    4)接着创建一个数据库管理器DatabaseManager.cs:

    复制代码
    publicclass DatabaseManager {     IDatabase _database;
       
    public DatabaseManager(IDatabase database)     {         _database = database;     }
       
    publicvoid Search(string commandText)     {         _database.Select(commandText);     }
       
    publicvoid Add(string commandText)     {             _database.Insert(commandText);     }
       
    publicvoid Save(string commandText)     {             _database.Update(commandText);     }
       
    publicvoid Remove(string commandText)     {             _database.Delete(commandText);     }
    }
    复制代码

    5)在控制台中,编写以下测试程序:

    复制代码
    var builder =new ContainerBuilder(); builder.RegisterType<DatabaseManager>(); builder.RegisterType<SqlDatabase>().As<IDatabase>(); using (var container = builder.Build()) {     var manager = container.Resolve<DatabaseManager>();     manager.Search("SELECT * FORM USER"); }
    复制代码

    运行结果:

    image

    分析:

    这里通过ContainerBuilder方法RegisterType对DatabaseManager进行注册,当注册的类型在相应得到的容器中可以Resolve你的DatabaseManager实例。

    builder.RegisterType<SqlDatabase>().As<IDatabase>();通过AS可以让DatabaseManager类中通过构造函数依赖注入类型相应的接口。

    Build()方法生成一个对应的Container实例,这样,就可以通过Resolve解析到注册的类型实例。

    同样地,如果你修改数据库类型注册为:

    builder.RegisterType<OracleDatabase>().As<IDatabase>();

    运行结果:

    image

    6)显然以上的程序中,SqlDatabase或者OracleDatabase已经暴露于客户程序中了,现在我想将该类型选择通过文件配置进行读取。Autofac自带了一个Autofac.Configuration.dll 非常方便地对类型进行配置,避免了程序的重新编译。

    修改App.config:

    复制代码
    <configuration>   <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></configuration>
    复制代码

    通过Autofac.Configuration.SectionHandler配置节点对组件进行处理。

    对应的客户端程序改为:

    复制代码
    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"); }
    复制代码

    运行结果:

    image

    7)另外还有一种方式,通过Register方法进行注册:

    复制代码
    var builder =new ContainerBuilder(); //builder.RegisterType<DatabaseManager>(); builder.RegisterModule(new ConfigurationSettingsReader("autofac")); builder.Register(c =>new DatabaseManager(c.Resolve<IDatabase>())); using (var container = builder.Build()) {     var manager = container.Resolve<DatabaseManager>();     manager.Search("SELECT * FORM USER"); }
    复制代码

    得到结果也是一样的。

    8)现在我想通过一个用户类来控制操作权限,比如增删改的权限,创建一个用户类:

    复制代码
    ///<summary>/// Id Identity Interface ///</summary>publicinterface Identity {     int Id { get; set; } }
    publicclass User : Identity {     publicint Id { get; set; }     publicstring Name { get; set; } }
    复制代码

    修改DatabaseManager.cs代码:

    复制代码
    publicclass DatabaseManager {     IDatabase _database;     User _user;
       
    public DatabaseManager(IDatabase database) : this(database, null)     {     }
       
    public DatabaseManager(IDatabase database, User user)     {         _database = database;         _user = user;     }
       
    ///<summary>     /// Check Authority     ///</summary>     ///<returns></returns>    publicbool IsAuthority()     {         bool result = _user !=null&& _user.Id ==1&& _user.Name =="leepy"?true : false;         if (!result)             Console.WriteLine("Not authority!");
           
    return result;     }
       
    publicvoid Search(string commandText)     {         _database.Select(commandText);     }
       
    publicvoid Add(string commandText)     {         if (IsAuthority())             _database.Insert(commandText);     }
       
    publicvoid Save(string commandText)     {         if (IsAuthority())             _database.Update(commandText);     }
       
    publicvoid Remove(string commandText)     {         if (IsAuthority())             _database.Delete(commandText);     } }
    复制代码

    在构造函数中增加了一个参数User,而Add,Save,Remove增加了权限判断。

    修改客户端程序:

    复制代码
    User user =new User { Id =1, Name ="leepy" }; var builder =new ContainerBuilder(); builder.RegisterModule(new ConfigurationSettingsReader("autofac")); builder.RegisterInstance(user).As<User>(); builder.Register(c =>new DatabaseManager(c.Resolve<IDatabase>(), c.Resolve<User>()));
    using (var container = builder.Build()) {     var manager = container.Resolve<DatabaseManager>();
        manager.Add(
    "INSERT INTO USER ..."); }
    复制代码

    运行结果:

    image 分析:

    builder.RegisterInstance(user).As<User>();注册User实例。

    builder.Register(c => new DatabaseManager(c.Resolve<IDatabase>(), c.Resolve<User>()));通过Lampda表达式注册DatabaseManager实例。

    如果这里我修改User的属性值:

    User user = new User { Id = 2, Name = "zhangsan" };

    运行结果:

    image

    说明该用户无权限操作。

    源代码下载:AutofacDemo.rar


    作者:Leepy
     
    邮箱:sunleepy(AT)gmail.com
     
  • 相关阅读:
    java中的 equals 与 ==
    String类的内存分配
    SVN用命令行更换本地副本IP地址
    npoi 设置单元格格式
    net core 微服务框架 Viper 调用链路追踪
    打不死的小强 .net core 微服务 快速开发框架 Viper 限流
    net core 微服务 快速开发框架 Viper 初体验20201017
    Anno 框架 增加缓存、限流策略、事件总线、支持 thrift grpc 作为底层传输
    net core 微服务 快速开发框架
    Viper 微服务框架 编写一个hello world 插件02
  • 原文地址:https://www.cnblogs.com/jzjblog/p/2749411.html
Copyright © 2011-2022 走看看