我使用autofac作为Ioc容器。 我有三个课程:
class Service
{
public Service(Repository rep,UnitOfWork context){}
}
Class Repository
{
public Repository(UnitOfWork context){}
}
class UnitOfWork{}
服务和存储库需要相同的UnitOfWork实例
怎么做? 以及如何在XmlConfiguration
中创建它答案 0 :(得分:31)
编辑:我误解了这一点,并认为这是一个关于如何使用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()
生成一个。{1}}。在现实生活中,你可能会要求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;
}
}
}