将ConstructedBy与非泛型For一起使用

时间:2012-06-29 17:09:25

标签: dependency-injection inversion-of-control structuremap

我在StructureMap中注册了

ObjectFactory.Initialize(x => {
    x.For<IPageModel>().UseSpecial(y => y.ConstructedBy( r => ((MvcHandler) HttpContext.Current.Handler).RequestContext.RouteData.GetCurrentModel<IPageModel>()));
});

然后我在我的构造函数中访问此对象,如此

public HomeController(IPageModel model) {}

现在我想注册所有实现接口IPageModel的具体类型,当被要求我想要使用相同的For&lt;&gt;声明以获得正确的实例。

似乎我可以将扫描与我自己的约定一起使用,但我无法弄明白该怎么做。

这是一些示例代码

x.Scan(scanner =>
{
    scanner.AssembliesFromApplicationBaseDirectory();
    scanner.Convention<MySpecialConvetion>();
});

public class MySpecialConvetion : IRegistrationConvention {
    public void Process(Type type, Registry registry) {
        if(type.IsAssignableFrom(typeof(IPageModel))) {
            registry.For<CONCRETE IMPLEMENTATION>().UseSpecial(y => y.ConstructedBy( r => ((MvcHandler) HttpContext.Current.Handler).RequestContext.RouteData.GetCurrentModel<CONCRETE IMPLEMENTATION>()));
        }
    }
}

编辑:好像我需要使用非泛型For,但是如何使用非泛型For来处理构造?

1 个答案:

答案 0 :(得分:0)

我通过创建通用方法定义来实现这一点,并使用反射来填充类型。比说明更容易展示:

    public class MySpecialConvetion : IRegistrationConvention
    {
        public static readonly MethodInfo RegisterMethod = typeof (MySpecialConvetion)
            .GetMethod("Register", BindingFlags.NonPublic | BindingFlags.Static)
            .GetGenericMethodDefinition();

        public void Process(Type type, Registry registry)
        {
            if (type.IsAssignableFrom(typeof (IPageModel)))
            {
                var specificRegisterMethod = RegisterMethod.MakeGenericMethod(new[] { type });
                specificRegisterMethod.Invoke(null, new object[] { registry });
            }
        }

        static private void Register<T>(Registry registry)
            where T : IPageModel
        {
            registry
                .For<T>()
                .UseSpecial(y => y.ConstructedBy(r => GetCurrentPageModel<T>()));
        }

        static private T GetCurrentPageModel<T>()
            where T : IPageModel
        {
            var handler = (MvcHandler) HttpContext.Current.Handler;
            if (handler == null)
                return default(T);
            return handler.RequestContext.RouteData.GetCurrentModel<T>();
        }
    }

我添加了一个中间步骤并检查了一个空处理程序,因为我的网站中没有一个。但这应该会让你失去你需要的东西。