2016-08-02 5 views
2

Я пытаюсь внедрить Injection Dependency из Core на моем программном обеспечении, чтобы заменить Ninject и обновить все до нашей новой технологии.Проблемы с впрыском зависимостей над MVC

Btw, я сталкиваюсь с проблемой на некоторых интерфейсах, которые являются общими. Для таких случаев я получаю прямо Исключение, что инжектор не смог создать экземпляр моего класса.

Я вставил над небольшим фрагментом образца, который меня поджег.

services.AddTransient(typeof(IRepository), typeof(MyRepository<,>)) 

Правильно ли это? Как я могу это сделать? Реализация

Класс:

public class MyRepository<TEntity, TContext> : IRepositoryBase 
    where TEntity : class 
    where TContext : IDbContext, new() 
{ 
... 
} 

Интерфейс:

public interface IRepository : IDisposable 
{ 
... 
} 

Спасибо!

+0

Вот как я делаю с моим внедрение зависимости хранилищ в ядре: services.AddScoped (); – lucas

+0

Существует четкое различие между вашим (Лукасом) и OP. Обратите внимание на открытые дженерики. Вы все еще используете фреймворк DI в ядре, ядро ​​просто предоставляет некоторые интерфейсы, чтобы легко подключить его. –

+0

Я все равно продолжаю удалять Ninject и добавлять что-то вроде Autofac, StructureMap или LightInject. Но в документации указано, что существует очень ограниченный набор функций, и я не думаю, что это распространяется на открытые дженерики. Мне нравится структура структуры из-за ее сборки на основе сборки на основе протоколов –

ответ

0

Я закончил с использованием Autofac и без каких-либо изменений на моя структура каждый вещь снова начала работать.

Подождите немного больше документации и больше людей, поэтому я могу изменить свою реализацию, чтобы использовать MS DI.

5

Это не имеет смысла. Вы спросите контейнер для IRepository, так как он узнает, какие аргументы общего типа должны быть такими, чтобы он мог дать вам MyRepository<,>?

Поэтому, когда просят вернуть объект вроде этого:

public class MyService 
{ 
    private IRepository<Something, SomethingElse> _repo; 

    public MyService(IRepository<Something, SomethingElse> repo) 
    { 
     // Container will actually give us MyRepository<Something, SomethingElse> 
     _repo = repo; 
    } 
} 

Я бы ожидать либо:

services.AddTransient(typeof(IRepository<,>), typeof(MyRepository<,>)); 

или, если хранилище не нужно быть общим (я не понять, почему это было бы нужно два общие аргументы, как это), то я бы ожидать, что это:

services.AddTransient(typeof(IRepository), typeof(MyRepository)); 

Однако, так как нет ни одного дженерик, участвующих здесь, вы можете использовать альтернативные формы для достижения тех же вещей с меньшей типизацией:

services.AddTransient<IRepository, MyRepository>(); 

Так на самом деле ответ должен решить дизайн интерфейса/класса. Показ большей части их реализации помог бы.

UPDATE

Ваша реализация должна быть: реализация

Класс:

public class MyRepository<TEntity, TContext> : IRepository<TEntity, TContext> 
    where TEntity : class 
    where TContext : IDbContext, new() 
{ 
... 
} 

Интерфейс:

public interface IRepository<TEntity, TContext> : IDisposable 
    where TEntity : class 
    where TContext : IDbContext, new() 
{ 
... 
} 
+0

Я согласен с тобой, но только по частям моя реализация действительно принимает это и имеет смысл. Я обновил свой вопрос с большим количеством фрагментов кода. –

+0

Извините, что не помогло. То, что вы показали, не будет работать на C#. У вас класс не имеет никакого отношения к интерфейсу, поэтому никакой контейнер не сможет сделать это для вас. Кроме того, не так, как правило, абстрактные классы имеют «базовое» соглашение суффикса, а не интерфейсы (у которых вместо этого есть префикс «I»). –

+0

Это действительно работает и поэтому работает над Ninject и Autofac, проблема заключается только в том, что Microsoft не принимает Generics –

0

Чтобы зарегистрировать все хранилищами использовать эту:

 var allRepositories = GetType().GetTypeInfo() 
     .Assembly.GetTypes().Where(p => 
      p.GetTypeInfo().IsClass && 
      !p.GetTypeInfo().IsAbstract && 
      typeof(IRepository).IsAssignableFrom(p)); 
     foreach (var repo in allRepositories) 
     { 
      var allInterfaces = repo .GetInterfaces(); 
      var mainInterfaces = allInterfaces.Except 
        (allInterfaces.SelectMany(t => t.GetInterfaces())); 
      foreach (var itype in mainInterfaces) 
      { 
       services.AddScoped(itype, repo); 
      } 
     } 

Затем решить ее:

public YourClass(IRepository<T> repo) 
{ 
    //... 
} 
+0

Мой код был почти таким, проблема не во всех регистрациях, а только тогда, когда это общий интерфейс, который бросает исключение на моем лице. Во всяком случае, спасибо за помощь –

+0

У меня есть аналогичный scenerio. У меня есть универсальный интерфейс IValidator (inherit from IValidator) и реализация этого интерфейса. Меня устраивает. –

+0

ОК, попробую еще раз здесь. –

Смежные вопросы