C# 如何在 Autofac 中注册这些类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11661501/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Register these class In Autofac
提问by DotDot
I am using autofac as Ioc Container. I have Three Classes:
我使用 autofac 作为 Ioc 容器。我有三个班级:
class Service
{
public Service(Repository rep,UnitOfWork context){}
}
Class Repository
{
public Repository(UnitOfWork context){}
}
class UnitOfWork{}
the Service and Repository need the same instance of UnitOfWork
Service 和 Repository 需要相同的 UnitOfWork 实例
How to do that? and How to wirte it in XmlConfiguration
怎么做?以及如何在 XmlConfiguration 中写入
回答by JaySilk84
EDIT:I misread this and thought it was a question about how to use autofac to register dependencies. If you want to keep the same UnitOfWork, you need to scope the lifetime of the instance to something. If you're using this in an ASP.NET or WCF application you can register your dependencies like this:
编辑:我误读了这个,并认为这是一个关于如何使用 autofac 注册依赖项的问题。如果您想保持相同的 UnitOfWork,您需要将实例的生命周期限定在某个范围内。如果您在 ASP.NET 或 WCF 应用程序中使用它,您可以像这样注册您的依赖项:
typeBuilder.RegisterType<UnitOfWork>().InstancePerLifetimeScope();
typeBuilder.RegisterType<Repository>();
typeBuilder.RegisterType<Service>();
First thing you need to do in order to use a container like Autofac is register all your dependencies. In Autofac you can do that a few ways but all of them rely on using the a ContainerBuilder. The ContainerBuilderrelies on extension methods so make sure you have a usingstatement for the Autofac namespace.
为了使用像 Autofac 这样的容器,您需要做的第一件事是注册您的所有依赖项。在 Autofac 中,您可以通过几种方式做到这一点,但所有这些都依赖于使用 a ContainerBuilder。将ContainerBuilder依赖于扩展方法,所以一定要确保你有一个using为Autofac namespace语句。
You can explicitly define the factory methods:
您可以显式定义工厂方法:
// 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>()));
Using ContainerBuilder we access the Register<>()method to provide the service interface (which is how we will be asking the container for the service) in this case, I'm not using interfaces, just the actual type. Any time you ask the container for a UnitOfWorkit will use the factory method new UnitOfWork()to generate one. In real life, you would probably be asking for an IUnitOfWork. This can all be a bit verbose, but it's very handy when you need custom logic for dependency creation.
Register<>()在这种情况下,我们使用 ContainerBuilder 访问提供服务接口的方法(这是我们向容器请求服务的方式),我没有使用接口,只是使用实际类型。任何时候你向容器请求一个,UnitOfWork它都会使用工厂方法new UnitOfWork()来生成一个。在现实生活中,您可能会要求一个IUnitOfWork. 这可能有点冗长,但是当您需要自定义逻辑来创建依赖关系时,它非常方便。
You can use the builder like any other dependency container and just register the types.
您可以像使用任何其他依赖项容器一样使用构建器,只需注册类型即可。
// Implicitly
var typeBuilder = new ContainerBuilder();
typeBuilder.RegisterType<UnitOfWork>();
typeBuilder.RegisterType<Repository>();
typeBuilder.RegisterType<Service>();
This approach relies on registering all the dependencies needed to build up a class. The container will then use reflection to resolve any constructor arguments. If an argument is not registered, the container will throw an exception with the type it could not resolve. In this case, the service has a dependency on UnitOfWorkand Repository. Repositoryalso has a dependency on UnitOfWork. These dependencies are expressed as constructor arguments. In order to request a Repositoryor a Servicefrom the container, all dependencies must be registered
这种方法依赖于注册构建类所需的所有依赖项。然后容器将使用反射来解析任何构造函数参数。如果未注册参数,则容器将抛出其无法解析的类型的异常。在这种情况下,服务依赖于UnitOfWork和Repository。Repository还依赖于UnitOfWork. 这些依赖项表示为构造函数参数。为了从容器请求 aRepository或 a Service,必须注册所有依赖项
You can use the configuration approach.
您可以使用配置方法。
If you're using an app.config file, you can define your config file like this:
如果你使用的是 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>
First, notice that we have to define a config section (notice the <ConfigSections>). Then, we can create an <autofac>section that defines all our dependencies. The notation is pretty simple, you basically create a <component>for every dependency. Each component has a serviceattribute which defines the type that will be requested. There is also a typeattribute that defines the object to be created when an instance of the service is requested. This is analogous to builder.Register<UnitOfWork>(b => new UnitOfWork())where UnitOfWorkis the service requested (and in this case) also the type to be created.
首先,请注意我们必须定义一个配置部分(注意<ConfigSections>)。然后,我们可以创建一个<autofac>定义所有依赖项的部分。符号非常简单,您基本上<component>为每个依赖项创建了一个。每个组件都有一个service属性,用于定义将被请求的类型。还有一个type属性定义了在请求服务实例时要创建的对象。这类似于builder.Register<UnitOfWork>(b => new UnitOfWork())在那里UnitOfWork被请求的服务(在这种情况下)也将被创建的类型。
To create the builder using the configuration, use a ConfigurationSettingsReader()
要使用配置创建构建器,请使用 ConfigurationSettingsReader()
// Config
var configBuilder = new ContainerBuilder();
configBuilder.RegisterModule(new ConfigurationSettingsReader("autofac"));
You have to pass in the name of your configuration section (in this case, autofac). Once you've configured the dependencies, you have to build a container. The ContainerBuildercontains a method to do this:
您必须传入配置部分的名称(在本例中为autofac)。配置依赖项后,您必须构建一个容器。该ContainerBuilder包含做到这一点的方法:
var container = builder.Build();
var typeContainer = typeBuilder.Build();
var configContainer = configBuilder.Build();
And once you have the container, you can request instances of your service:
一旦你有了容器,你就可以请求你的服务实例:
container.Resolve<Service>().DoAwesomeness();
typeContainer.Resolve<Service>().DoAwesomeness();
configContainer.Resolve<Service>().DoAwesomeness();
Complete program:
完整程序:
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;
}
}
}

