【问题标题】:Unity 2.1 - Resolve generic type from non-generic interface?Unity 2.1 - 从非泛型接口解析泛型类型?
【发布时间】:2012-03-28 21:33:18
【问题描述】:

我正在使用 Unity(通过配置文件强制进行配置),我现在有点卡住了。问题比较长,可以跳到场景、问题和问题,配置/代码供参考。

非常感谢您的帮助!

配置

<register type="IService" mapTo="DefaultService" name="Context1" />
<register type="IService" mapTo="ExtendedService" name="Context2" />

<register type="IManager" mapTo="DefaultManager" name="Context1" />
<register type="IManager" mapTo="ExtendedManager" name="Context1" />

代码

public interface IService 
{
    void DoSomething();
}

public class DefaultService : IService 
{
    protected IManager Manager { 
        return Container.Resolve<IManager>(ContextBasedName());
    }

    public void DoSomething() {
        Manager.DoSomething();
    }
}

public class ExtendedService : DefaultService 
{

}

public interface IManager  
{
    void DoSomething();
}

public class DefaultManager : IManager 
{
    protected virtual void DoSomething() 
    {
        //Do something default
    }
}

public class ExtendedManager : DefaultManager
{
    protected override void DoSomething() 
    {
        //First do something special

        base.DoSomething(); //then the default
    }
}

场景

我有两个 context,其中解析了基于 IService 的类型(Context1Context2)。 ContextBasedName() 将为实际上下文返回正确的字符串。

Context1内:

//Will return DefaultService
var service = Container.Resolve<IService>(ContextBasedName());

service.DoSomething(); //Will eventually call DefaultManager.DoSomething();

内部Context2

//Will return ExtendedService
var service = Container.Resolve<IService>(ContextBasedName()); 

service.DoSomething(); //Will eventually call ExtendedManager.DoSomething();

问题:

上述情况很好,但是问题与上面的无法编译的代码有关。由于DefaultService 类中的Manager 属性定义,它无法编译:

protected IManager Manager { 
    return Container.Resolve<IManager>(ContextBasedName());
}

IManager 泛型类型未在类级别定义。据我所知,只有两种解决方案:

  1. Manager 属性更改为方法并像这样调用:.Manager&lt;IManager&gt;()
  2. IManager 泛型类型添加到类并以某种方式在 Unity 解析方法中注入该类型即使解析接口不是泛型的

问题:

关于 1:为什么不能在属性上指定泛型类型?

关于2:即使接口不是通用的,是否可以在解析方法或配置中指定具体类型?

【问题讨论】:

    标签: generics interface unity-container


    【解决方案1】:

    为什么不使用构造函数注入并为每个服务配置正确的管理器的注入?

    目前您正在以service locator 的身份滥用容器。


    更新

    如果您需要提供运行时值,请为管理器注入工厂而不是管理器实例。

    【讨论】:

    • 但这意味着我必须配置不可能的构造函数值。我正在使用一个特殊的 ContextBasedName() 方法,它在运行时提供一个名称...
    • 使用容器解析机制作为工厂有什么问题?
    • @Ropstah 您是否查看了我的答案中包含的链接?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多