Autofac自注册TypedNamedAndKeyedServices

时间:2013-04-14 01:16:34

标签: c# inversion-of-control ioc-container autofac caliburn.micro

我有一个简单的系统,根据用户选择的 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之间做的一样?

1 个答案:

答案 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正在做的事情(但是有一些正则表达式的魔法,可能还有更少的泛型?)