c# - library - autofac description
Registrar Tipo Genérico con Autofac (1)
Tengo clase UnitofWork e implemento IUnitOfWork. Intento registrarlo con autofac:
var builder = new ContainerBuilder();
builder
.RegisterGeneric(typeof(UnitOfWork<Repository<>,>))
.As(typeof(IUnitOfWork))
.InstancePerDependency();
La implementación es:
public class UnitOfWork<T, O> : IUnitOfWork
where T : Repository<O>
where O : BaseEntity
{
}
public interface IUnitOfWork : IDisposable
{
void SaveChanges();
}
Da un error "Tipo esperado"
pero éste trabaja en otro proyecto:
public class Repository<T> : GenericRepository<T>
where T : BaseEntity
{
public Repository(IDbContext context)
: base(context) { }
}
public abstract class GenericRepository<T>
: IRepository<T>, IQueryable<T> where T : BaseEntity
{
}
builder
.RegisterGeneric(typeof(Repository<>))
.As(typeof(IRepository<>))
.InstancePerHttpRequest();
No puede tener clases parcialmente abiertas (por ejemplo, con UnitOfWork<Repository<>,>
ha especificado T
pero no O
) dentro de una typeof
, inténtelo con:
var builder = new ContainerBuilder();
builder
.RegisterGeneric(typeof(UnitOfWork<,>))
.As(typeof(IUnitOfWork))
.InstancePerDependency();
La restricción genérica where T : Repository<O>
se ocupará de que el primer argumento sea un Repository<>
Pero no funcionará con RegisterGeneric
porque requiere una interfaz genérica, por lo que debe crear un IUnitOfWork<T,O>
...
Pero tu modelo es muy extraño. ¿Por qué su UnitOfWork
necesita un argumento de tipo Repository<>
?
En lugar de tenerlo como un argumento de tipo, puede obtener un Repository<>
en su UnitOfWork<E>
:
public class UnitOfWork<E> : IUnitOfWork<E> where E : BaseEntity
{
private readonly Repository<E> repository;
public UnitOfWork(Repository<E> repository)
{
this.repository = repository;
}
//.. other methods
}
Donde IUnitOfWork<E>
public interface IUnitOfWork<E> : IDisposable where E : BaseEntity
{
void SaveChanges();
}
Y el registro de Autofac:
var builder = new ContainerBuilder();
builder
.RegisterGeneric(typeof(Repository<>)).AsSelf();
builder
.RegisterGeneric(typeof(UnitOfWork<>))
.As(typeof(IUnitOfWork<>))
.InstancePerDependency();
var container = builder.Build();
// sample usage
var u = container.Resolve<IUnitOfWork<MyEntity>>();