简体   繁体   English

Ninject:将相同的接口绑定到两个实现

[英]Ninject: Bind same interface to two implementations

I have a project called Infrastructure , which contains an interface IRepository 我有一个名为Infrastructure的项目,它包含一个接口IRepository

public interface IRepository<T>
{
    /// <summary>
    /// Adds the specified entity to the respository of type T.
    /// </summary>
    /// <param name="entity">The entity to add.</param>
    void Add(T entity);

    /// <summary>
    /// Deletes the specified entity to the respository of type T.
    /// </summary>
    /// <param name="entity">The entity to delete.</param>
    void Delete(T entity);
}

In my solution, i have two other projects 在我的解决方案中,我有两个其他项目

  • Application.Web Application.Web
  • Application.Web.Api Application.Web.Api
  • Infrastructure 基础设施

Both projects, contains an implementation of the IRepository interface 这两个项目都包含IRepository接口的实现

public class EFRepository<T> : IRepository<T>
{
    // DbContext for Application.Web project
    ApplicationWebDbContext _db;
    public EFRepository(ApplicationWebDbContext context)
    {
        _db = context;
    }

    public void Add(T entity) { }
    public void Delete(T entity) { }
}

public class EFRepository<T> : IRepository<T>
{
    // DbContext for Application.Web.Api project
    ApplicationWebAPIDbContext _db;
    public EFRepository(ApplicationWebAPIDbContext context)
    {
        _db = context;
    }

    public void Add(T entity) { }
    public void Delete(T entity) { }
}

Both implementations works with different DataContexts . 这两种实现都适用于不同的DataContexts

How can I bind this in ninject? 我如何在ninject中绑定它?

private static void RegisterServices(IKernel kernel)
{
    // bind IRepository for `Application.Web` project
    kernel.Bind(typeof(IRepository<>)).To(typeof(Application.Web.EFRepository<>));

    // bind IRepository for `Application.Web.Api' project
    kernel.Bind(typeof(IRepository<>)).To(typeof(Application.Web.Api.EFRepository<>));    
}

There are several appoaches to resolve such situations 几种方法可以解决这种情况

Named binding 命名绑定

Simplest, just provide name for dependency: 最简单,只提供依赖的名称:

kernel
        .Bind(typeof(IRepository<>))
        .To(typeof(WebApiEFRepository<>))
        // named binding
        .Named("WebApiEFRepository");

And resolve it using this name. 并使用此名称解决它。 Name cound be found in configuration: web.config for example: 名称可以在配置中找到: web.config例如:

var webApiEFRepository = kernel.Get<IRepository<Entity>>("WebApiEFRepository");

Contextual binding 上下文绑定

Find from injection context what type to bind. 注入上下文中查找要绑定的类型。 In your example based on target namespace 在基于目标命名空间的示例中

kernel
    .Bind(typeof(IRepository<>))
    .To(typeof(WebDbRepository<>))
    // using thins binding when injected into special namespace
    .When(request => request.Target.Type.Namespace.StartsWith("Application.Web"));

Get dependency from kernel: 从内核获取依赖:

// WebDbRepository<> will be injected
var serice = kernel.Get<Application.Web.Service>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM