我有一个简单的系统,根据用户选择的 Molecule 的类型显示不同的屏幕(WPF)。为了实现它,我将Caliburn.Micro与Autofac一起用作Ioc容器。
预计会有一个简单的命名约定:
[MoleculeName]< - > [MoleculeName] ViewModel - > [MoleculeName]视图
Caliburn.Micro提供了view / viewmodel约定,我的目标是复制Molecule< - > MoleculeViewModel部件的约定。
每个分子都由一个类型代表,并且继承自 IMolecule
public Interface IMolecule {...}
IoC由AutoFac提供,以下工作正常:
private void ConfigureMoleculesLibs(Autofac.ContainerBuilder builder)
{
var builder = new ContainerBuilder();
// get assemblies
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
// register molecules
builder
.RegisterAssemblyTypes(assemblies)
.Where(t => t.IsAssignableTo<IMolecule>())
.AsSelf();
// register molecules view models
builder
.RegisterType<H2SO4MoleculeViewModel>()
.Keyed<Type>(TypeOf(H2SO4Molecule));
builder
.RegisterType<HClMoleculeViewModel>()
.Keyed<Type>(TypeOf(HClMolecule));
builder
.RegisterType<H2oMoleculeViewModel>()
.Keyed<Type>(TypeOf(H2oMolecule));
}
以便允许以下内容:
public class MoleculeWrapperViewModel : Screen
{
public delegate MoleculeWrapperViewModel Factory(IMolecule molecule);
public MoleculeWrapperViewModel(
IIndex<Type, Screen> moleculeScreensLookup,
IMolecule molecule)
{
this.MoleculeViewModel = moleculeScreensLookup[molecule.GetType()];
}
public Screen MoleculeViewModel { get; private set; }
}
有没有办法通过匹配名称和相应的ViewModel来自动注册Keyed Types,就像Caliburn在Views和ViewModel之间做的一样?
答案 0 :(得分:0)
听起来你想在这里使用一点反射来遍历所有分子类型并调用相应的AutoFac
泛型方法
您需要使用分子类型来生成类型名称:
var viewModelTypeName = moleculeTypeName + "ViewModel";
Type yourViewModelType = Type.GetType(viewModelTypeName); // Not 100% on the syntax here, don't have VS open :P
Type type = typeof(ContainerBuilder);
MethodInfo miGeneric = type.GetMethod("RegisterType");
MethodInfo mi = miGeneric.MakeGenericMethod(yourViewModelType);
mi.Invoke(...) // etc
显然它有点复杂,因为你链接方法(不确定RegisterType
返回什么 - 可能是类型注册对象?)并且你必须为第一个返回对象的泛型方法提供这个打电话等
你尝试过这样的方法吗?
不确定AutoFac
是否支持这样的开箱即用 - 但实质上这就是CM正在做的事情(但是有一些正则表达式的魔法,可能还有更少的泛型?)