2012-07-26 7 views
8

Estoy usando autofac como Ioc Container. tengo tres clases:Cómo registrar estas clases En Autofac

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

} 

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

class UnitOfWork{} 

el Servicio y Repositorio necesitan la misma instancia de UnitOfWork

Cómo hacer eso? y Cómo wirte en XmlConfiguration

+0

I lo siento, mi inglés es pobre – DotDot

Respuesta

30

EDIT: leí mal esto y pensé que era una pregunta acerca de cómo usar autofac para registrar las dependencias. Si desea mantener el mismo UnitOfWork, necesita extender el tiempo de vida de la instancia a algo. Si está usando esto en una aplicación ASP.NET o WCF puede registrar sus dependencias así:

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

Lo primero que hay que hacer con el fin de utilizar un recipiente como Autofac es registrar todos dependencias. En Autofac puede hacerlo de varias maneras, pero todos ellos confían en usar el a ContainerBuilder. El ContainerBuilder depende de los métodos de extensión, así que asegúrese de tener una declaración using para el espacio de nombres Autofac.

Puede definir explícitamente los métodos de fábrica:

// 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>())); 

Uso ContainerBuilder que acceden al método Register<>() para proporcionar la interfaz de servicio (que es como vamos a solicitar el contenedor para el servicio) en este caso , No estoy usando interfaces, solo el tipo real. Cada vez que solicite al contenedor un UnitOfWork, utilizará el método de fábrica new UnitOfWork() para generar uno. En la vida real, probablemente estarías pidiendo un IUnitOfWork. Todo esto puede ser un poco detallado, pero es muy útil cuando se necesita una lógica personalizada para la creación de dependencias.

Puede usar el constructor como cualquier otro contenedor de dependencia y simplemente registrar los tipos.

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

Este enfoque se basa en registrar todas las dependencias necesarias para construir una clase. El contenedor utilizará la reflexión para resolver cualquier argumento de constructor. Si no se registra un argumento, el contenedor emitirá una excepción con el tipo que no pudo resolver. En este caso, el servicio tiene una dependencia en UnitOfWork y Repository. Repository también tiene una dependencia en UnitOfWork. Estas dependencias se expresan como argumentos de constructor. Con el fin de solicitar una Repository o una Service del contenedor, todas las dependencias deben estar registrados

Se puede utilizar el método de configuración.

Si está utilizando un archivo app.config, se puede definir el archivo de configuración de esta manera:

<?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> 

En primer lugar, el aviso de que tenemos que definir una sección de configuración (nótese la <ConfigSections>). Entonces, podemos crear una sección <autofac> que defina todas nuestras dependencias. La notación es bastante simple, básicamente creas un <component> para cada dependencia.Cada componente tiene un atributo service que define el tipo que se solicitará. También hay un atributo type que define el objeto que se creará cuando se solicita una instancia del servicio. Esto es análogo a builder.Register<UnitOfWork>(b => new UnitOfWork()) donde UnitOfWork es el servicio solicitado (y en este caso) también el tipo que se creará.

Para crear el constructor utilizando la configuración, use un ConfigurationSettingsReader()

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

Usted tiene que pasar en el nombre de la sección de configuración (en este caso, autofac). Una vez que haya configurado las dependencias, debe construir un contenedor. El ContainerBuilder contiene un método para hacer esto:

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

Y una vez que tenga el contenedor, puede solicitar instancias de su servicio:

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

Programa completo:

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

No tengo '' 'ConfigurationSettingsReader''' constructor, ¿de dónde viene eso? – HoKy22

+0

http://stackoverflow.com/questions/39364698/autofac-upgrade-to-version-4-0-0-is-missing-configurationsettingsreader ¿Cómo hacerlo para Autofac 4.2? – HoKy22

Cuestiones relacionadas