2012-07-26 161 views
8

我使用autofac作爲Ioc容器。 我有三類:如何註冊這些類在Autofac

class Service 
{ 
    public Service(Repository rep,UnitOfWork context){} 

} 

Class Repository 
{ 
    public Repository(UnitOfWork context){} 
} 

class UnitOfWork{} 

服務和信息庫需要的UnitOfWork

的同一實例如何做到這一點? 以及如何WIRTE它XMLConfiguration中

+0

我對不起,我的英文很差 – DotDot 2012-07-26 02:35:14

回答

30

編輯:我誤解這一點,並認爲這是一個有關如何使用autofac註冊的依賴問題。如果你想保持相同的UnitOfWork,你需要將實例的生命期限定爲某種東西。如果你在一個ASP.NET或WCF應用程序中使用這個,你可以這樣註冊您的依賴關係:你需要

typeBuilder.RegisterType<UnitOfWork>().InstancePerLifetimeScope(); 
typeBuilder.RegisterType<Repository>(); 
typeBuilder.RegisterType<Service>(); 

的第一件事,以便使用的容器做這樣Autofac是註冊您的所有依賴。在Autofac中,您可以通過幾種方法來實現,但所有這些方法都依賴於使用a ContainerBuilderContainerBuilder依賴於擴展方法,因此請確保您有一個用於Autofac名稱空間的using語句。

您可以明確定義的工廠方法:

// Explicitly 
var builder = new ContainerBuilder(); 
builder.Register<UnitOfWork>(b => new UnitOfWork()); 
builder.Register<Repository>(b => new Repository(b.Resolve<UnitOfWork>())); 
builder.Register(b => new Service(b.Resolve<Repository>(), b.Resolve<UnitOfWork>())); 

使用ContainerBuilder我們訪問Register<>()方法來提供服務接口(這是我們如何將要求該服務的容器),在這種情況下, ,我沒有使用接口,只是實際的類型。任何時候你問容器的UnitOfWork它將使用工廠方法new UnitOfWork()生成一個。在現實生活中,你可能會要求IUnitOfWork。這可能有點冗長,但是當您需要自定義邏輯來創建依賴關係時,它非常方便。

您可以像使用任何其他依賴容器一樣使用構建器並只註冊類型。

// Implicitly 
var typeBuilder = new ContainerBuilder(); 
typeBuilder.RegisterType<UnitOfWork>(); 
typeBuilder.RegisterType<Repository>(); 
typeBuilder.RegisterType<Service>(); 

這種方法依賴於註冊建立一個類所需要的所有的依賴。容器然後將使用反射來解析任何構造函數參數。如果一個參數未被註冊,那麼容器將拋出一個它無法解析的類型的異常。在這種情況下,服務依賴於UnitOfWorkRepositoryRepository也依賴於UnitOfWork。這些依賴關係表示爲構造函數參數。爲了從容器中請求RepositoryService,必須註冊所有相關性

您可以使用配置方法。

如果您使用的是app.config文件,你可以定義你的配置文件是這樣的:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/> 
    </configSections> 

    <autofac defaultAssembly="AutoFacTest"> 
    <components> 
     <component 
       type="AutoFacTest.Repository, AutoFacTest" 
       service="AutoFacTest.Repository" /> 

     <component 
       type="AutoFacTest.UnitOfWork, AutoFacTest" 
       service="AutoFacTest.UnitOfWork" /> 

     <component 
       type="AutoFacTest.Service, AutoFacTest" 
       service="AutoFacTest.Service" /> 
    </components> 
    </autofac> 
</configuration> 

首先,我們必須定義一個配置部分(注意<ConfigSections>)的通知。然後,我們可以創建一個定義我們所有依賴項的<autofac>部分。符號很簡單,你基本上爲每個依賴創建一個<component>。每個組件都有一個service屬性,它定義了將要請求的類型。還有一個type屬性,用於定義在請求服務實例時要創建的對象。這與builder.Register<UnitOfWork>(b => new UnitOfWork())類似,其中UnitOfWork是所請求的服務(在這種情況下)也是要創建的類型。

若要使用配置生成器,使用ConfigurationSettingsReader()

// Config 
var configBuilder = new ContainerBuilder(); 
configBuilder.RegisterModule(new ConfigurationSettingsReader("autofac")); 

您的配置部分的名稱通過(在這種情況下,autofac)。一旦你配置了依賴關係,你就必須建立一個容器。該ContainerBuilder包含做到這一點的方法:

var container = builder.Build(); 
var typeContainer = typeBuilder.Build(); 
var configContainer = configBuilder.Build(); 

而且一旦你有容器,你可以要求你的服務的實例:

container.Resolve<Service>().DoAwesomeness(); 
typeContainer.Resolve<Service>().DoAwesomeness(); 
configContainer.Resolve<Service>().DoAwesomeness(); 

完整的程序:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Autofac; 
using Autofac.Configuration; 

namespace AutoFacTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Explicitly 
      var builder = new ContainerBuilder(); 
      builder.Register<UnitOfWork>(b => new UnitOfWork()); 
      builder.Register<Repository>(b => new Repository(b.Resolve<UnitOfWork>())); 

      builder.Register(b => new Service(b.Resolve<Repository>(), b.Resolve<UnitOfWork>())); 

      // Implicitly 
      var typeBuilder = new ContainerBuilder(); 
      typeBuilder.RegisterType<UnitOfWork>(); 
      typeBuilder.RegisterType<Repository>(); 
      typeBuilder.RegisterType<Service>(); 

      // Config 
      var configBuilder = new ContainerBuilder(); 
      configBuilder.RegisterModule(new ConfigurationSettingsReader("autofac")); 

      var container = builder.Build(); 
      var typeContainer = typeBuilder.Build(); 
      var configContainer = configBuilder.Build(); 


      container.Resolve<Service>().DoAwesomeness(); 
      typeContainer.Resolve<Service>().DoAwesomeness(); 
      configContainer.Resolve<Service>().DoAwesomeness(); 
      Console.Read(); 
     } 
    } 

    public class Repository 
    { 
     private readonly UnitOfWork _unitOfWork; 
     public Repository(UnitOfWork uow) 
     { 
      _unitOfWork = uow; 
     } 

     public void PrintStuff(string text) 
     { 
      Console.WriteLine(text); 
     } 
    } 

    public class Service 
    { 
     private readonly Repository _repository; 
     private readonly UnitOfWork _unitOfWork; 

     public Service(Repository repo, UnitOfWork uow) 
     { 
      _repository = repo; 
      _unitOfWork = uow; 
     } 
     public void DoAwesomeness() 
     { 
      _repository.PrintStuff("Did awesome stuff!"); 
      _unitOfWork.Commit(); 
     } 
    } 

    public class UnitOfWork 
    { 
     public bool Commit() 
     { 
      return true; 
     } 
    } 


} 
+0

我沒有'''ConfigurationSettingsReader'''的構造函數,從哪裏來的呢? – HoKy22 2016-12-20 18:22:23

+0

http://stackoverflow.com/questions/39364698/autofac-upgrade-to-version-4-0-0-is-missing-configurationsettingsreader如何爲Autofac 4.2做到這一點? – HoKy22 2016-12-20 18:25:02