Зарегистрировать общий тип с Autofac - программирование
Подтвердить что ты не робот

Зарегистрировать общий тип с Autofac

У меня есть класс UnitofWork и он реализует IUnitOfWork. Я пытаюсь зарегистрировать это с помощью autofac:

var builder = new ContainerBuilder();
builder
    .RegisterGeneric(typeof(UnitOfWork<Repository<>,>))
    .As(typeof(IUnitOfWork))
    .InstancePerDependency();

Реализация:

public class UnitOfWork<T, O> : IUnitOfWork
    where T : Repository<O>
    where O : BaseEntity
{
}

public interface IUnitOfWork : IDisposable
{
    void SaveChanges();
}

Дает ошибку "Ожидаемый тип"

но эта работа работает над другим проектом:

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();
4b9b3361

Ответ 1

Вы не можете частично открывать классы (например, с UnitOfWork<Repository<>,> вы указали T, но не O) внутри typeof, попробуйте с

var builder = new ContainerBuilder();
builder
    .RegisterGeneric(typeof(UnitOfWork<,>))
    .As(typeof(IUnitOfWork))
    .InstancePerDependency();

Общее ограничение where T : Repository<O> позаботится о том, чтобы первым аргументом был Repository<>

Но он не будет работать с RegisterGeneric, потому что для этого требуется общий интерфейс, поэтому необходимо создать IUnitOfWork<T,O>...

Но ваша модель очень странная. Почему ваш UnitOfWork нужен аргумент типа Repository<>?

Вместо того, чтобы иметь его как аргумент типа, вы можете получить Repository<> в своем конструкторе 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

}

Где IUnitOfWork<E>

public interface IUnitOfWork<E> : IDisposable where E : BaseEntity
{
    void SaveChanges();
}

И регистрация 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>>();