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;
}
}
}
I lo siento, mi inglés es pobre – DotDot