web-dev-qa-db-fra.com

Enregistrer le type générique avec Autofac

J'ai la classe UnitofWork et elle implémente IUnitOfWork. J'essaye d'enregistrer avec autofac:

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

La mise en œuvre est:

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

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

Donne une erreur "Type attendu"

mais celui-ci travaille sur un autre projet:

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();
28
shortcode

Vous ne peut pas avoir des classes partiellement ouvertes (par exemple avec UnitOfWork<Repository<>,> vous avez spécifié T mais pas O) dans un typeof, essayez avec:

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

Le where T : Repository<O> la contrainte générique fera en sorte que le premier argument soit un Repository<>

Mais cela ne fonctionnera pas avec RegisterGeneric car il nécessite une interface générique donc besoin de créer un IUnitOfWork<T,O>

Mais votre modèle est très étrange. Pourquoi votre UnitOfWork a-t-elle besoin d'un Repository<> argument de type?

Au lieu de l'avoir comme argument de type, vous pouvez obtenir un Repository<> dans ton UnitOfWork<E> constructeur:

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

Et l'inscription 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>>();
59
nemesv