首页 > 解决方案 > MVC 5 / UnityConfig - 相同的接口 - 多种实现

问题描述

所以我有这个基本界面:

public interface ISearchable
{
    List<AutocompleteResult> Search(string term);
}

还有两个实现这个接口的类:

头等舱:

public class LandlordReader :ISearchable
{
    public List<AutocompleteResult> Search(string term)
    {
        ....
    }
}

二等:

public class CityReader : ISearchable
{
    public List<AutocompleteResult> Search(string term)
    {
       ....
    }
}

从这一点开始,我一无所知......在 UnityConfig.cs 我试图通过给它们一个名字来注册它们:

public static void RegisterTypes(IUnityContainer container)
{
    container.RegisterType<ISearchable, CityReader>("City");
    container.RegisterType<ISearchable, LandlordReader>("Landlord");
}

在 MVC 控制器中,我不知道要指定什么(在构造函数中) - 告诉它我想要一个或另一个:

public LandlordController(ISearchable searcher)
{
    // I want the LandlordReader here, but in the CityController, I want the CityReader....
    this.searcher = searcher;
}

关于 DI 和 UnityInjector,我是个菜鸟,所以一个完整的工作示例会很好。到目前为止,我得到了很多建议(使用通用接口,使用统一工厂) - 但我自己尝试过,没有一个奏效。

我知道在 ASP.NET Core 中有一个属性可以直接在构造函数的参数列表中指定,但我目前正在使用 MVC5。

谢谢。写完一篇长文。呸。

标签: c#asp.netasp.net-mvcdependency-injectionunity-container

解决方案


如果适合您的场景,您可以尝试这些选项之一。

1

使用命名服务注入

public static void RegisterTypes(IUnityContainer container)
{
    container.RegisterType<ISearchable, CityReader>("City");
    container.RegisterType<ISearchable, LandlordReader>("Landlord");
}

public LandlordController([Dependency("Landlord")]ISearchable searcher)
{
    this.searcher = searcher;
}

2

public interface ISearchable<T> where T : class
{
//..............
}

public class LandlordReader : ISearchable<LandlordReader>
{
    public List<AutocompleteResult> Search(string term)
    {
        ....
    }
}

public class CityReader : ISearchable<CityReader>
{
    public List<AutocompleteResult> Search(string term)
    {
       ....
    }
}
public static void RegisterTypes(IUnityContainer container)
{
        container.RegisterType<ISearchable, CityReader>("City");
        container.RegisterType<ISearchable, LandlordReader>("Landlord");
}

然后在构造函数中使用时执行此操作

    private readonly ISearchable<CityReader> _cityReadersearcher;
    private readonly ISearchable<LandlordReader> _landLordsearcher;
    public LandlordController(ISearchable<CityReader> cityReadersearcher, 
     ISearchable<LandlordReader> landLordsearcher)
    {
         _cityReadersearcher= _cityReadersearcher;
        _landLordsearcher = landLordsearcher;
    }

推荐阅读