我有一个接口INavigationService
和一个简单的容器,允许使用和不使用密钥进行注册。
这对我很有用,因为框架会将已注册的实例注入我的视图模型的构造函数中。
现在我有多个导航服务(由于我的UI中的帧)。它们都实现了相同的基本界面(INavigationService
)。
我希望能够让容器将这些实例注入正确的导航树(框架+后续视图/视图模型),而不必传递参数(DI注册密钥)。
这通常是怎么做的?
我可以想象基于属性的东西(因此将注册密钥放在所有依赖类定义上)。但是容器不支持这个。这似乎也很麻烦。
我还可以创建一个专门用于标记的界面。所以INavigationService<T>
并使用不同的类型参数注册每个导航服务。例如。框架的第一个视图的类型。这将给我我需要的解决方案,虽然我会传递没有任何意义的接口。
另一方面,我获得IDE支持以查找依赖视图(例如通过创建类似FileTreeNavigation : INavigationService<FileTreeView>
还有其他模式吗?
答案 0 :(得分: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容器解决的类。该课程取决于ServiceA
和ServiceB
,定义如下:
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
的实例,其中ServiceA
和ServiceB
的实例已正确构建(NavigationServiceA
和NavigationServiceB
,分别)。
这是一种方法,我发现它更直接。还有可能做Conditional Construction,但我认为这可能会非常复杂。
PS:搜索“caliburn micro constructor”我偶然发现了this approach,这与我在使用StructureMap做的相似(只是在这里它是叫InjectionConstructor
)。