【问题标题】:Ninject: Bind same interface to two implementationsNinject:将相同的接口绑定到两个实现
【发布时间】:2013-01-14 08:46:18
【问题描述】:

我有一个名为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);
}

在我的解决方案中,我还有另外两个项目

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

两个项目都包含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) { }
}

两种实现都适用于不同的DataContexts

如何在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<>));    
}

【问题讨论】:

  • 在使用每个存储库时是否有一些标准?
  • 恐怕不行。他们只是使用相同的界面,所以我不必为我拥有的每个项目复制 IRepository 界面
  • 当您请求存储库时,Ninject 应该如何知道它应该使用两种实现中的哪一种呢?它应该随机选择一个吗?
  • 这是我的问题..我认为这可能是实现这一目标的一种方式
  • ???需要有一些标准可以选择一个,否则有两个实现是没有意义的。制定这个标准,你可以得到帮助。这种标准的一个示例可能是:“如果需要存储库的类在程序集Application.Web.Api 中定义,则使用实现Application.Web.Api.EFRepository&lt;T&gt;。”另一个标准可能是:“如果需要存储库的类是从 API 进程实例化的,请使用 Application.Web.Api.EFRepository&lt;T&gt;。”

标签: c# asp.net-mvc ninject ninject.web.mvc


【解决方案1】:

several appoaches解决此类情况

命名绑定

最简单的,只需提供依赖的名称:

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

并使用此名称解决它。名称可以在配置中找到:web.config 例如:

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

上下文绑定

injection context 中查找要绑定的类型。 在基于目标命名空间的示例中

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

从内核获取依赖:

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

【讨论】:

    最近更新 更多