Ninject GetAll Where Module = foo

时间:2012-11-21 22:41:25

标签: c# .net ninject

是否可以做这样的事情:

var foos = Kernel.where(c=>c.module == myModule).GetAll<foo>;

怎么会这样呢?

如果(!可能)
使用GetAll()方法时,如何区分绑定到同一接口? 我知道WithParameterWithMetadataWithConstructorArgumentWithPropertyValue;我应该使用哪一个?为什么?

干杯


更多信息

我需要这个,因为我正在创建一个插件框架。在路由期间,插件框架需要能够确定要查看哪个控制器。如果插件中有多个家庭控制器,它将无法按预期工作 我需要能够区分哪个插件注册了哪个IController实现,以便控制器工厂知道将请求发送到特定插件中的控制器。

3 个答案:

答案 0 :(得分:0)

您是否考虑过使用When(),所以您不必这样做?

即。

Bind<IInterface>().To<YourConcreteTypeOne>().When(r => r.Target.Name == "concreteObjectOne"); 

根据已接受的解决方案(更新部分)中的建议here。理想情况下,在设置绑定后,您不应该真正需要访问内核,否则您将自己与DI框架紧密结合。如果这不适用,请扩展您的问题以包含更多代码。

答案 1 :(得分:0)

一种简单的方法是定义一个具有IControllerProviderName方法的GetController接口。您的核心产品加载所有扫描的IControllerProvider实现并获取控制器并使用名称和内核中的Icontroller实例注册它们。通过这种方法,您的插件可以使用自己的容器或只是做穷人DI。然后,您的路由处理程序可以获取IEnumerable<IController>。或者最好简单地将名称放在IController界面上,这样就不需要回退到ninject元数据。

答案 2 :(得分:0)

我最终将元数据附加到每个元素:

Bind<IController>().To<MyController>()
   .Named(implementation.GetType().Name.Replace("Controller", string.Empty))
   .WithMetadata("Plugin", PluginName);`

然后像我这样路由我的插件:

routes.MapRoute(
                name: "Plugin1",
                url: "Plugin1/{controller}/{action}/{id}",
                defaults: new { Plugin = PluginName, controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

并在控制器工厂中使用GetControllerType方法

object requestedModule;
if (requestContext.RouteData.Values.TryGetValue("Plugin", out requestedPlugin))
    controller = kernel.GetAll<IController>(c => c.Name == controllerName && c.Get<string>("module", string.Empty) == (string)requestedPlugin).SingleOrDefault();