1. 程式人生 > 實用技巧 >Autofac(01)

Autofac(01)

本章內容

  • 控制反轉
  • 依賴注入
  • Autofac的使用

1.控制反轉

1.1耦合

多重依賴關係,在物件和各模組都會出現。一個類知道互動類的大量資訊就是高耦合,修改這個類就容易破壞互動類

1.2降低耦合

  • 在兩塊程式碼之間引入抽象層
public interface IMessageService
{
void SendMessage();
}

public class EmailService : IMessageService
{
public  void SendMessage()
{
Console.WriteLine("通過電子郵件傳送訊息");
}
}

public class
MessageManager { private IMessageService msgService; public MessageManager() { msgService=new EmailService(); } public void SendMsg() { msgService.SendMessage(); } }
引入抽象層
  • 把選擇抽象實現的責任移除到消費者的外部

需要把EmailService類的建立移到MessageManager類的外面。

1.3控制反轉

把依賴移除到依賴類的外部,稱為控制反轉。是抽象的,只表示移除

2.依賴注入

依賴注入是一種控制反轉的形式,注入方式通常採用兩種:

  • 建構函式注入

只需儲存一個介面,不需依賴項

public class MessageManager
{
private IMessageService msgService;

public MessageManager(IMessaageService service)
{
msgService=service;
}

public void SendMsg()
{
msgService.SendMessage();
}
}
  • 屬性注入

設定物件上的公共屬性

public class MessageManager
{
public IMessageService msgService {get
; set;} public void SendMsg() { if (msgService ==null) { Throw new InvalidOperationException(); } msgService.SendMessage(); } }

3.依賴注入框架

Autofac是一款IOC容器框架,輕量級,效能高。

3.1Autofac的使用

  • 安裝Autofac
    // 資料來源操作介面
    public interface IDataSource
    {
        // 獲取資料
        string GetData();
    }

    // SQLSERVER資料庫
    public class Sqlserver : IDataSource
    {
        public string GetData()
        {
            return "通過SQLSERVER獲取資料";
        }
    }

    // ORACLE資料庫
  public class Oracle : IDataSource
    {
        public string GetData()
        {
            return "通過Oracle獲取資料";
        }
    }

   /// 資料來源管理類
      public class DataSourceManager
  {

          IDataSource _ds;
        // 根據傳入的型別動態建立物件
        public DataSourceManager(IDataSource ds)
        {
            _ds = ds;
        }

      public string GetData()
        {
            return _ds.GetData();
        }
    }

    static void Main(string[] args)
    {
         //獲取Autofac容器構造器
        var builder = new ContainerBuilder();

        // 註冊型別
    builder.RegisterType<DataSourceManager>();

        // 註冊例項(即將SqlServer型別註冊為IDataSource的例項
         builder.RegisterType<Sqlserver>().As<IDataSource>();

        // 由構造器建立Ioc容器
         using (var container = builder.Build())
         {
            // 解析例項
             var manager = container.Resolve<DataSourceManager>();   
            Console.WriteLine(manager.GetData());
       Console.ReadLine();
         }
     }
Autofac基本用法
  • 其他用法:①註冊多個介面

        builder.RegisterType<Sqlserver>().AsImplementedInterfaces();

        ②利用反射註冊

        Assembly asm = Assembly.Load("DAL.BLL");builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces();

        我們可以在配置檔案中將程式集資訊在<appSettings>節點中進行配置,來減少對程式集的引用,徹底解除耦合。

        ③利用屬性注入註冊

        Assembly asm = Assembly.Load("DAL.BLL");builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces().PropertiesAutowired();

       ④一個介面多個實現

Assembly asm = Assembly.Load("DAL.BLL");
builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces();
using (var container = builder.Build())
{
    IEnumerable<IDataSource> dals =
           container.Resolve<IEnumerable<IDataSource>>();

   foreach(var dal in dals)
   {
       Console.WriteLine(dal.GetData());
   }
    Console.ReadLine();
}

//也可以通過Named()方法在指定要想獲取的型別。
 //獲取Autofac容器構造器
        var builder = new ContainerBuilder();

        // 註冊型別
   builder.RegisterType<DataSourceManager>();

        // 註冊例項
      builder.RegisterType<Sqlserver>().Named<IDataSource>("SqlServer");
      builder.RegisterType<Sqlserver>().Named<IDataSource>("Oracle");

        // 由構造器建立Ioc容器
      using (var container = builder.Build())
      {
            // 解析例項
         var manager = container.ResolveNamed<DataSourceManager>("SqlServer");    
         Console.WriteLine(manager.GetData());
    Console.ReadLine();
      }

3.2通過配置方式使用Autofac

通過配置實現Autofac 需要新增對Autofac.Configuration.dll的引用。

配置檔案
<configuration>
  <configSections>
    <section name="autofac" type="Autofac.Configuration.SectionHandler,Autofac.Configuration"></section>
  </configSections>
  <autofac defaultAssembly="AutoFacDemo">
    <components>
      <component  type="AutoFacDemo.Model.Oracle,AutoFacDemo" service="AutoFacDemo.Model.IDataSource" />
    </components>
  </autofac>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

C#程式碼
var builder = new ContainerBuilder();
builder.RegisterType<DataSourceManager>();
builder.RegisterModule(
      new ConfigurationSettingsReader("autofac" ));
配置

4.在Asp.net Mvc中使用Autofac

  • 安裝
  • 建立配置類
public class AutofacConfig
{
    public static void Register()
    {
        var builder = new ContainerBuilder();
        //載入當前程式集
    Assembly controllerAss = Assembly.GetExecutingAssembly();

        //Assembly controllerAss = Assembly.Load("OA.Web");
        //註冊所有的Controller
        builder.RegisterControllers(controllerAss).PropertiesAutowired();

        //註冊資料訪問層程式集
        Assembly resAss = Assembly.Load("OA.DAL");
        builder.RegisterTypes(resAss.GetTypes()).AsImplementedInterfaces();

        //註冊業務層程式集
        Assembly bllAss = Assembly.Load("OA.BLL");
        builder.RegisterTypes(bllAss.GetTypes()).AsImplementedInterfaces();

        var container = builder.Build();
        //當mvc建立controller物件的時候,都是由AutoFac為我們建立
        //Controller物件
        DependencyResolver.SetResolver(new
                 AutofacDependencyResolver(container));
    }
}
建立配置
  • 註冊自己的控制類
在Global.asax 的Application_Start() 註冊自己的控制器類

protected void Application_Start()
{
     AreaRegistration.RegisterAllAreas();
     RouteConfig.RegisterRoutes(RouteTable.Routes);
     //Autofac配置
     AutofacConfig.Register();
}
至此,在MVC中使用 Autofac 的配置步驟完成。
 
在Controller中的使用如下:
public class HomeController :Controller
{
public IDataSource dataSource { get ; set; }

public  ActionResult Index( )
{
var data = dataSource.GetData( );
return View(data);
}
}