Зарегистрируйте универсальный тип, используя лямбда-выражение с параметром в AutoFac - PullRequest
0 голосов
/ 04 апреля 2019

Я пытаюсь сделать это , но с универсальным классом вроде:

public class BaseRepository<TEntity> : IBaseRepository<TEntity>, IDisposable
    where TEntity : class, new()
    {
        public BaseRepository(IIndex<ContextKey, IDbContextBase> factory, ContextKey key)
        {
            Context = factory[key];
            Set = Context.Set<TEntity>();
        }
}

Чтобы я мог передать ключ ContextKey в качестве параметра.

Я пытаюсь динамически разрешить dbcontext на основе того, какой ключ был передан в ctor класса BaseRepository<>.

Зарегистрируйтесь это так:

builder.Register((c, p) =>
                 new BaseRepository<>(p.Named<ContextKey>("key")))
       .As<IBaseRepository<>>();

Разрешить как:

var reader = scope.Resolve<IBaseRepository<ActionEntity>>(
new NamedParameter("key", ContextKey.Applications));

Ключ передается:

public enum ContextKey
{
    Pure, Phoebus, Applications, Legacy, None
}

и параметр factory встроен в Autofac - его автоинъекция и обработка выполняются Autofac.

1 Ответ

2 голосов
/ 04 апреля 2019

Наличие IIndex<ContextKey, IDbContextBase> factory, ContextKey key в конструкторе хранилища во многом похоже на проблемы реализации, которые можно делегировать корню композиции.

Сначала я бы упростил конструктор хранилища, следуя принципу явной зависимости.

public class BaseRepository<TEntity> : IBaseRepository<TEntity>, IDisposable
    where TEntity : class, new() {

    //...

    public BaseRepository(IDbContextBase context) {
        Context = context;
        Set = Context.Set<TEntity>();
    }

    //...
}

В этом случае корень композиции будет ответственен за обеспечение правильного построения хранилища.

ContextKey key = //known value

//...Assumes IIndex<ContextKey, IDbContextBase> factory is registered

builder
    .RegisterGeneric(typeof(BaseRepository<>))
    .As(typeof(IBaseRepository<>))
    .WithParameter(
        new ResolvedParameter(
            (pi, ctx) => pi.ParameterType == typeof(IDbContextBase) && pi.Name == "context",
            (pi, ctx) => {
                var factory = ctx.Resolve<IIndex<ContextKey, IDbContextBase>>();
                return factory[key];
            })
    );

//...

var container = builder.Build();

Обратите внимание на использование ResolvedParameter для динамического получения параметра, который будет введен в хранилище.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...