Ninject GetAll Where Module = foo

我的未来我决定 提交于 2019-12-12 04:47:24

问题


Is it possible to do something like this:

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

And how would one go about it?

If(!possible)
How can you discriminate between bindings to the same interface when using the GetAll() method?
I am aware of WithParameter, WithMetadata, WithConstructorArgument and WithPropertyValue; Which one should i use and why?

Cheers


More information

I need this because I am creating a plugin framework. During the routing the plugin framework needs to be able to determine which controller's to look at. If there are multiple home controllers across plugins it wont work as expected.
I need to be able to differentiate which plugin registered which IController implementation so that the controller factory knows to send the request to a controller in a specific plugin.


回答1:


Have you considered looking at using When(), so you don't have to do this?

i.e.

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

As suggested here in the accepted solution (updated section). Ideally you shouldn't really need to access the kernel after you've set your bindings otherwise you're tightly coupling yourself to your DI framework. If this isn't applicable please do expand your question to include more code.




回答2:


A simple approach is that you define an interface i.e. IControllerProvider which has a Name and a GetController method. Your core product loads all scanned IControllerProvider implementations and gets the controllers and registers them with a name and the Icontroller instace in the kernel. With that approach your plugins can use their own containers or simply do poor man DI. Your routing handler can then acquire an IEnumerable<IController>. Or better simply put the name onto the IController interface, so that you don't need t fallback to ninject metadata.




回答3:


I ended up attaching metadata to each one:

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

Then routing my plugins like so:

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

And in the controller factory GetControllerType method

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();


来源:https://stackoverflow.com/questions/13503239/ninject-getall-where-module-foo

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!