【问题标题】:Unity via configuration - property dependency injection in generic base classUnity via configuration - 通用基类中的属性依赖注入
【发布时间】:2012-07-30 11:21:28
【问题描述】:

我迷失了寻找解决这个问题的方法:

我有接口:

public interface ITestService
{
    ...
}

然后,我有一个基类,它实现了该接口并有其他服务作为属性:

public class BaseTestServiceImpl<T> : ITestService, IDisposable where T : class
{
    protected T GenericProperty;

    public IOtherService OtherService;

    public void ExampleMethodFromBase()
    {
        OtherService.DoSomething();
    }

    public void Dispose()
    {
        ....
    }
}

最后,我有几个继承该基类的类。其中之一的示例:

public class SpecificTestServiceImpl : BaseTestServiceImpl<SomeType>
{
    public void ExampleMethodFromSpecific()
    {
        OtherService.DoSomethingElse();
    }
}

SpecificTestServiceImpl 调用方法的控制器如下所示:

public class TestController : Controller
{
    [Dependency("TestService")]
    public BaseTestServiceImpl<SomeType> TestService { get; set; }

    public JsonResult TestAction()
    {
        TestService.ExampleMethodFromSpecific();
    }
}

Unity 配置如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

    <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
    </configSections>

    <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <container>
        <alias alias="transient" type="Microsoft.Practices.Unity.TransientLifetimeManager, Microsoft.Practices.Unity" />
        <alias alias="MyType" type="SomeType" />
        <register name="otherService" type="IOtherService" mapTo="OtherServiceImpl">
            <lifetime type="singleton" />
        </register>
        <register type="ITestService" mapTo="BaseTestServiceImpl`1[]">
            <lifetime type="transient" />
            <property name="OtherService" dependencyName="otherService" />
        </register>
        <register name="TestService" type="BaseTestServiceImpl`1[MyType]" mapTo="SpecificTestServiceImpl">
            <lifetime type="singleton" />
        </register>
    </container>
    </unity>
</configuration>

一切都解决得很好,直到 TestController 中的 TestAction 被调用。然后我在这一行得到 NullPointerException:

OtherService.DoSomethingElse();

SpecificTestServiceImplExampleMethodFromSpecific 方法中。

Unity 似乎在子类中跳过了父属性注入。

这可以吗?我尝试将其他生命周期管理器设置为 BaseTestServiceImpl 注册,但以同样的方式失败。

请帮忙。我迷路了。 :(

提前感谢。

【问题讨论】:

  • 为什么要在 XML 中拥有完整的配置?您应该只在 XML 中配置在部署期间实际上可以更改的部分 DI 配置。其余的,使用基于代码的配置,因为基于 XML 的配置表达能力较差、更脆弱、容易出错且难以维护。

标签: c# inheritance configuration dependency-injection unity-container


【解决方案1】:

现在我使用 unity 已经有一段时间了,我更喜欢将配置完全放在代码中,但是: 控制器中请求的类型是[Dependency("TestService")],它被配置为SpecificTestServiceImpl,而SpecificTestServiceImpl 又没有被配置。我原以为 Unity 会告诉你 SpecificTestServiceImpl 没有配置,但也许它确实使用了映射类型,这是具体的

我只需要补充一点,这种公共成员、接口、注入的具体类型的组合是相当糟糕的封装逻辑,并且删除了很多正确设计所具有的价值。测试控制器最好请求一个接口 ISomeTypeTestService(或类似接口),该接口又可以映射到 BaseTestServiceImpl,或者它可以是一个命名的 ITestService,可以像现在一样被请求

【讨论】:

  • 首先我要感谢您的回答。至于您的建议-我已经简化了代码,以便我可以更轻松地解释我的问题,因此即使我尝试制作有效的示例,也可能存在一些明显的错误。我很确定问题在于父->子注册解析,因为 Unity 配置已解决且没有任何错误。
  • 好的,但请检查您请求的类型是否已将属性配置为依赖项,因为就像现在的示例一样,您正在请求具有属性但未配置任何内容的类型它作为要解决的依赖项。尝试将依赖属性添加到基类中的otherservice:[Dependency]public IOtherService OtherService;
  • Unity 配置中的这一行进行注入:&lt;property name="OtherService" dependencyName="otherService" /&gt;
  • 是的,但这不是控制器请求的依赖项
  • Controller 正在请求 TestService 依赖项,并且该依赖项工作得很好,因为它在 ExampleMethodFromSpecific() 方法内崩溃,其中 OtherServicenull 因此 Unity 无法解决.
猜你喜欢
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-28
  • 2015-07-07
  • 2019-04-13
相关资源
最近更新 更多