C# 每个模块的统一寄存器/解析接口

C# 每个模块的统一寄存器/解析接口,c#,dependency-injection,inversion-of-control,unity-container,prism,C#,Dependency Injection,Inversion Of Control,Unity Container,Prism,我们的Prism应用程序使用一个全局IRegionManager和作用域IRegionManager用于子模块。当我初始化我的模块子模块a时,我创建了一个新的作用域RegionManagerRegionManager。我想将此作用域RegionManager注册为IRegionManager,但仅在该模块内解析时注册 例如,搜索视图/视图模型通过4个子模块共享,并获得IRegionManager注入。当这个共享的SearchView加载到SubModuleA中时,unity应该注入RegionM

我们的
Prism
应用程序使用一个全局
IRegionManager
和作用域
IRegionManager
用于
子模块
。当我初始化我的模块
子模块a
时,我创建了一个新的作用域RegionManager
RegionManager
。我想将此作用域RegionManager注册为
IRegionManager
,但仅在该模块内解析时注册

例如,
搜索
视图/视图模型通过4个子模块共享,并获得
IRegionManager
注入。当这个共享的
SearchView
加载到
SubModuleA
中时,unity应该注入
RegionManagerA
等等


我知道使用ninject会容易得多,但时间安排是,
ninject
不会在接下来的几个sprint中实现;)

我对Unity不太熟悉,所以我不能给你精确的解,但我可以给你解决这个问题的一般模式。这里使用的模式是代理模式。您应该为IRegionManager创建一个代理,该代理可以将调用转发给应该使用的区域管理器

例如:

public class SelectorRegionManagerProxy : IRegionManager
{
    private readonly Func<IRegionManager> selector;
    public SelectorRegionManagerProxy(Func<IRegionManager> selector) {
        this.selector = selector;
    }

    // IRegionManager method(s) here.
    void IRegionManager.AnnoyEmployees() {
        this.selector.Invoke().AnnoyEmployees();
    }
}

只有
RunningInScopeOfSubModuleA()
检查的实现是我无法帮助您的。

依赖项重写经常被忽略,可以在这里使用。您可以让每个模块使用命名注册来注册自己的区域管理器

然后,在每个模块中指定特定替代,以确保将正确的区域管理器传递到viewmodel中:

//ModuleA
container.RegisterType<IRegionManager, RegionManagerA>("RegionManagerA")

//ModuleB
container.RegisterType<IRegionManager, RegionManagerB>("RegionManagerB")

//Some other point in Module B
//Resolve the specific RegionManager for Module B
DependencyOverride rm = new DependencyOverride(typeof(IRegionManager)
                         ,container.Resolve<IRegionManager>("RegionManagerB")); 

//and pass that as a dependency when the SearchViewModel is resolved
SearchViewModel vm = container.Resolve<SearchViewModel>(rm);
//模块a
container.RegisterType(“RegionManager”)
//模B
container.RegisterType(“RegionManagerB”)
//模块B中的其他一些点
//解析模块B的特定RegionManager
DependencyOverride rm=新DependencyOverride(类型为(IRegionManager))
,container.Resolve(“RegionManagerB”);
//并在解析SearchViewModel时将其作为依赖项传递
SearchViewModel vm=container.Resolve(rm);

谢谢你的评论,但我认为有些逻辑正在逐渐形成。注册可以在Bottsrapper/MainShell和子模块中完成,因此逻辑必须是:-可以使用条件将多个实例注册到同一接口-基于此条件解析实例。我建议不要使用
DependencyOverride
s,正如我建议不要使用子容器来覆盖依赖项一样。可以看出,这很容易出错。如果
SearchViewModel
(或其依赖于
IRegionManager
的子依赖项之一)是单例,则应用程序将以静默方式中断。这当然会起作用,但您需要注意,实际上有一个名为的不同RegionManager。我的意图是,在这个模块中,我想解决一个不同的RegionManager。所以某种魔力:D
//ModuleA
container.RegisterType<IRegionManager, RegionManagerA>("RegionManagerA")

//ModuleB
container.RegisterType<IRegionManager, RegionManagerB>("RegionManagerB")

//Some other point in Module B
//Resolve the specific RegionManager for Module B
DependencyOverride rm = new DependencyOverride(typeof(IRegionManager)
                         ,container.Resolve<IRegionManager>("RegionManagerB")); 

//and pass that as a dependency when the SearchViewModel is resolved
SearchViewModel vm = container.Resolve<SearchViewModel>(rm);