3

我有一个界面INavigationService和一个简单的容器,允许使用和不使用密钥进行注册。

这对我很有用,因为框架会将注册的实例注入到我的视图模型的构造函数中。

现在我有多个导航服务(由于我的 UI 中的框架)。它们都实现了相同的基本接口 ( INavigationService)。

我希望能够让容器将这些实例注入正确的导航树(框架 + 后续视图/视图模型),而无需传递参数(DI 注册密钥)。

这通常是怎么做的?

我可以想象一些基于属性的东西(因此将注册密钥放在所有依赖类定义中)。但容器不支持这一点。似乎也很麻烦。

我还可以创建一个专门用于标记的界面。因此INavigationService<T>,并使用不同的类型参数注册每个导航服务。例如帧的第一个视图的类型。这会给我我需要的解决方案,尽管我会传递没有任何意义的接口。

另一方面,我获得了 IDE 对查找依赖视图的支持(例如,通过创建类似FileTreeNavigation : INavigationService<FileTreeView>

还有其他模式吗?

4

1 回答 1

1

我不确定这如何适用于 Caliburn Micro,但由于问题是关于模式的,我将在这里描述我设法用StrucureMap解决这个问题的方法:使用Ctor<>允许为构造函数参数解析指定具体类型的方法。

另外,我认为使用专用接口(您的FileTreeNavigation示例)很棒,但是如果由于某种原因您认为这不合适,请继续阅读。

假设我们有INavigationService接口和两个不同的实现:

public interface INavigationService { }
public class NavigationServiceA : INavigationService { }
public class NavigationServiceB : INavigationService { }

接下来,我们有两个不同的 Service 类,都依赖于INavigationService接口:

public class ServiceA
{
    private readonly INavigationService _navigationService;

    public ServiceA(INavigationService navigationService)
    {
        _navigationService = navigationService;
    }
}

public class ServiceB
{
    private readonly INavigationService _navigationService;

    public ServiceB(INavigationService navigationService)
    {
        _navigationService = navigationService;
    }
}

最后,我们有一个将使用 IoC 容器解析的类。该类同时依赖于ServiceAServiceB,定义如下:

public class SomeClassToResolve
{
    private readonly ServiceA _serviceA;
    private readonly ServiceB _serviceB;

    public SomeClassToResolve(ServiceA serviceA, ServiceB serviceB)
    {
        _serviceA = serviceA;
        _serviceB = serviceB;
    }
}

StructureMap 提供了指定使用什么类型来解析构造函数参数的可能性。这是注册的样子:

ForConcreteType<ServiceA>().Configure.Ctor<INavigationService>().Is<NavigationServiceA>();
ForConcreteType<ServiceB>().Configure.Ctor<INavigationService>().Is<NavigationServiceB>();

现在,当我调用container.GetInstance<SomeClassToResolve>();它时,它将构造一个 的实例SomeClassToResolve,该实例具有 的实例ServiceAServiceB正确构造(分别具有NavigationServiceANavigationServiceB)。

这是一种方法,我发现它更直接。也有可能进行Conditional Construction,但我认为这会变得非常复杂。

PS:搜索“caliburn 微构造函数”时,我偶然发现了这种方法,它看起来与我使用 StructureMap 所做的类似(只是这里称为InjectionConstructor)。

于 2012-10-14T11:48:10.177 回答