如何在Autofac中注册这些类

Dot*_*Dot 11 c# dependency-injection ioc-container autofac

我使用autofac作为Ioc容器.我有三个课程:

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

}

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

class UnitOfWork{}
Run Code Online (Sandbox Code Playgroud)

Service and Repository需要UnitOfWork的相同实例

怎么做?以及如何在XmlConfiguration中创建它

Jay*_*k84 31

编辑:我误解了这一点,并认为这是一个关于如何使用autofac来注册依赖项的问题.如果要保持相同的UnitOfWork,则需要将实例的生命周期作为范围.如果您在ASP.NET或WCF应用程序中使用它,您可以注册您的依赖项,如下所示:

typeBuilder.RegisterType<UnitOfWork>().InstancePerLifetimeScope();
typeBuilder.RegisterType<Repository>();
typeBuilder.RegisterType<Service>();
Run Code Online (Sandbox Code Playgroud)

要使用像Autofac这样的容器,您需要做的第一件事就是注册所有依赖项.在Autofac中,您可以通过几种方式实现这一点,但所有这些方法都依赖于使用a ContainerBuilder.将ContainerBuilder依赖于扩展方法,所以一定要确保你有一个using为Autofac namespace语句.

您可以显式定义工厂方法:

// 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>()));
Run Code Online (Sandbox Code Playgroud)

Register<>()在这种情况下,我使用ContainerBuilder访问提供服务接口的方法(这就是我们要求容器获取服务的方法),我不使用接口,只是实际类型.每当你向容器询问UnitOfWork它时,它将使用工厂方法new UnitOfWork()生成一个.在现实生活中,你可能会要求一个IUnitOfWork.这可能都有点冗长,但是当您需要用于创建依赖关系的自定义逻辑时,它非常方便.

您可以像使用任何其他依赖项容器一样使用构建器,只需注册类型即可.

// Implicitly
var typeBuilder = new ContainerBuilder();
typeBuilder.RegisterType<UnitOfWork>();
typeBuilder.RegisterType<Repository>();
typeBuilder.RegisterType<Service>();
Run Code Online (Sandbox Code Playgroud)

这种方法依赖于注册构建类所需的所有依赖项.然后容器将使用反射来解析任何构造函数参数.如果未注册参数,则容器将抛出具有无法解析的类型的异常.在这种情况下,服务依赖于UnitOfWorkRepository.Repository也依赖于UnitOfWork.这些依赖项表示为构造函数参数.为了从容器中请求a Repository或a 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>
Run Code Online (Sandbox Code Playgroud)

首先,请注意我们必须定义一个配置部分(注意<ConfigSections>).然后,我们可以创建一个<autofac>定义所有依赖项的部分.符号很简单,你基本上<component>为每个依赖创建一个.每个组件都有一个service属性,用于定义将要请求的类型.还有一个type属性定义了在请求服务实例时要创建的对象.这类似于builder.Register<UnitOfWork>(b => new UnitOfWork())在那里UnitOfWork被请求的服务(在这种情况下)也将被创建的类型.

要使用配置创建构建器,请使用a ConfigurationSettingsReader()

// Config
var configBuilder = new ContainerBuilder();
configBuilder.RegisterModule(new ConfigurationSettingsReader("autofac"));
Run Code Online (Sandbox Code Playgroud)

您必须传入配置部分的名称(在本例中autofac).一旦配置了依赖项,就必须构建一个容器.该ContainerBuilder包含做到这一点的方法:

var container = builder.Build();
var typeContainer = typeBuilder.Build();
var configContainer = configBuilder.Build();
Run Code Online (Sandbox Code Playgroud)

一旦你有了容器,你可以请求你的服务实例:

container.Resolve<Service>().DoAwesomeness();
typeContainer.Resolve<Service>().DoAwesomeness();
configContainer.Resolve<Service>().DoAwesomeness();
Run Code Online (Sandbox Code Playgroud)

完整计划:

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;
        }
    }


}
Run Code Online (Sandbox Code Playgroud)