編輯:我誤解這一點,並認爲這是一個有關如何使用autofac註冊的依賴問題。如果你想保持相同的UnitOfWork,你需要將實例的生命期限定爲某種東西。如果你在一個ASP.NET或WCF應用程序中使用這個,你可以這樣註冊您的依賴關係:你需要
typeBuilder.RegisterType<UnitOfWork>().InstancePerLifetimeScope();
typeBuilder.RegisterType<Repository>();
typeBuilder.RegisterType<Service>();
的第一件事,以便使用的容器做這樣Autofac是註冊您的所有依賴。在Autofac中,您可以通過幾種方法來實現,但所有這些方法都依賴於使用a ContainerBuilder
。 ContainerBuilder
依賴於擴展方法,因此請確保您有一個用於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>();
這種方法依賴於註冊建立一個類所需要的所有的依賴。容器然後將使用反射來解析任何構造函數參數。如果一個參數未被註冊,那麼容器將拋出一個它無法解析的類型的異常。在這種情況下,服務依賴於UnitOfWork
和Repository
。 Repository
也依賴於UnitOfWork
。這些依賴關係表示爲構造函數參數。爲了從容器中請求Repository
或Service
,必須註冊所有相關性
您可以使用配置方法。
如果您使用的是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;
}
}
}
我對不起,我的英文很差 – DotDot 2012-07-26 02:35:14