Autofac to resolve generic controller - c#

I am having a master data service which is a generic one. Example: IMasterDataService<T>
I am trying to build an Api controller for this in a similar fashion like MasterDataController<T>. I want to resolve the controller using autofac, but I can't find any documentation for the same.
When I tried, I'm getting the error message as unable to resolve the type.
I am registering like builder.RegisterGeneric for the service, but controller I'm not getting instance and I would like to know if this is possible at all.

Well, anyways, you cannot resolve generic class at runtime. You need to parameterize it. This means that before resolving generic controller you must have a type to close this generic. The only reasonable source of said type that comes to my mind is the request itself, otherwise controller would not be generic, it just doesn't make sense to me. So, you'll need to craft your type using incoming request somehow, and then resolve your controller based on that type using some kind of custom controller factory or activator or whatever it is called in the framework you're using. In the .NET Core, for example, that would be IControllerActivator, and you'll need to register controllers in the DI container using .AddControllersAsServices() extension before doing that.
EDIT There's actually such an implementation for dotnet core right in the Microsoft's documentation. But they use slightly different technique: they do not actually register an open generic controller. They make all predefined variants of closed generic controllers and register them instead. I think that this is due to the fact that Microsoft's IoC container cannot resolve closed generic types from open generic registrations - at least it could not do that in .NET Core 1.x, I haven't tried it in 2.0 yet. However, it is possible with Autofac, so I think such an approach should work.
Another possibility here could be to inject IComponentContext into non-generic controller and resolve master data service "on the fly" in the controller itself crafting the type needed to close generic right there in the controller.
Anyways, this is a generic answer to a generic question. If you need more detailed answer you'll need to provide more insight into what you're doing.

Related

ASP.NET Core - Overriding the default ControllerFactory

I'm in a very specific situation where I'd like to override the default ASP.NET Core ControllerFactory. I'd like to do this because I want to be in full control of what type of controller I handle each request with.
The scenario is:
Request comes in with a specific subdomain
Based on this subdomain, I want to resolve a Generic type controller in the factory
For example:
category.website.com is called
We see it's of type category and will use the generic HomeController<T> , using DI to inject the category so the type is of HomeController<Category>
The HomeController<Category> will use some generic methods on type Category methods to render the homepage.
If I'm led to believe this link, a factory of type DefaultControllerFactory is registered on startup of the application. This seems to not be overridable.
Any idea how I would go by this? The most logical options for us is using the old ASP.NET MVC version which allows you to set your own ControllerFactory, but we'd lose features like being able to use SpaServices to prerender our Angular application.
Register your own implementation in ConfigureServices, after calling AddMvc:
services.AddSingleton<IControllerFactory, MyCustomControllerFactory>();
This way it will get called whenever a controller is to be built.
For completeness the best way is to actually implement an IControllerActivator and register it, since the default controller factory is not public. It will use whatever implementation of IControllerActivator is registered to actually create the controller class.

Does Unity MVC resolve types by default?

I'm new to DI scenarios and I'm implementing a DI scenario using Unity and asp.net mvc.
I was trying to inject a DbContex instance into my UnitOfWork class. I registered the instance but I noticed that DbContexobject had been already injected without writing the code for resolving the DbContex.
How it could be possible? Does Unity resolving the instances by default?
I thought it was my responsibility to write this "resolving code" for the DI to work.
For instance, when I'm injecting dependencies into Controllers I must write a code like this in GetControllerInstance method:
return MvcUnityContainer.Container.Resolve(controllerType) as IController;
You need to only resolve the root object, e.g., the controller class. Unity would then look at the constructor of this class and will see that it has some dependencies (constructor parameters). It will then automatically try to resolve these dependencies. If these dependencies have dependencies themselves, it will resolve these first...
This process is called auto-wiring. Without auto-wiring, why would anyone use a DI container? (Not that I think that you should use one in the first place)
Unity by default "registers" all concrete types loaded in the process - so you can call .Resolve with concrete type and get result (assuming constructor of that type actually can get called by Unity).
For interfaces you need to register mapping to concrete type/instances so.

Autofac Constructor Injection by Attribute

I have a class that currently takes an IIndex in order to select an indexed dependency. I'd like to change that to somehow using an attribute on the constructor argument, in order to directly specify which one to use.
I'm pretty sure Autofac doesn't support this natively, but I'm not afraid to write my own attribute for this. I've messed around with the source side of Autofac before (custom registration sources, etc.) but I've never seen a way of tailoring the injection side. Can anyone help?
P.S.: I've seen this question but it turned into a discussion on the benefits of attribute-based injection. OTOH, I already decided I don't want to have to manually register each one of my types that depends on this particular dependency one-by-one, so I'd prefer it.
You can achieve this by scanning your class metadata on resolving an interface. When you get info about its parameters you can resolve actual implementation of the interface. See my answer here.
I noticed http://code.google.com/p/autofac/wiki/WebFormsIntegration says we can create a Custom Dependency Injection Models by implementing IInjectionBehaviour, I think it worth a try.

How can I create a unit test that verifies that all fluent validators can be resolved by Windsor?

I am using FluentValidation in my application to verify my entities, but I have come up with a little issue. My validation factory is setup to resolve validation classes from Windsor by attempting to resolve from the IValidator<EntityType> interface.
I want to make sure that whenever a validation class is creating that no one forgets to register it with Windsor.
Essentially I want to look at all classes in the assembly that implement the IValidator<EntityType> interface and call WindsorContainer.Resolve(typeof(IValidator<EntityType>)) to resolve that type, where EntityType can be any class in the assembly. So far, using reflection I have been able to pull out all classes that are derived from the generic interface IValidator<> but I can't figure out how to proceed from there. The problem is I would have to find some way to pull out the actual entity used in the generic in order to call Windsor correctly, and I am at a loss of how to do that.
Is there an easier way to do this?
I want to make sure that whenever a validation class is creating that no one forgets to register it with Windsor.
Why are you doing this? You should have an installer that automatically discovers these validation classes and registers them for you. Then you only need to test that you coded the installer correctly.
The fact that someone adds a class that implements IValidator<TEntity> for some TEntity shouldn't break your code!
The problem is I would have to find some way to pull out the actual entity used in the generic in order to call Windsor correctly, and I am at a loss of how to do that.
You want Type.GetGenericArguments.

Castle Windsor to create instance of object based on URL parameters?

Is it possible for me to get Castle Windsor to inject an object that has been created with URL parameters? Either as query string parameters or parameters defined in a routing configuration?
Currently this object is being passed in to the Controller's Index action method, but I need to have it available in the constructor.
If so, what do I need to do?
I would start by looking at the documentation.
The scenario sounds really hacky, but if you really wanted to do this I would recommend implementing a custom controller factory.
There, you can control the instantiation of your controllers.

Categories

Resources