2016-08-02 141 views
2

我试图在我的软件上实现从核心的依赖注入,以取代Ninject并更新所有新技术。MVC上的依赖注入问题

顺便说一句,我在通用的一些接口上遇到问题。对于这种情况,我直接获得一个Exception,注入器无法创建我的类的实例。

我插在样本案例的一小段代码上面,使我着火。

​​

这样正确吗?我怎样才能做到这一点?

类实现:

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

接口:

public interface IRepository : IDisposable 
{ 
... 
} 

谢谢!

+0

这里是我正在做我的核心库的DependencyInjection:services.AddScoped (); – lucas

+0

你(lucas)和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的DI不接受泛型 –

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 (继承自IValidator)通用接口和此接口的实现。这个对我有用。 –

+0

好吧,让我再试一次。 –