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.
Related
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.
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.
Probably you can give me a hint about good practices: In order to learn a bit more about Web API, I'm trying to create a Web-Service which helps doing some work with the TFS.
It would be very cool, if the Client could select, which TFS he wants to use by passing kindahow an object, which contains the needed data since TFS Service URL etc. But this gives me some troubles:
I created a type called TFSConfiguation, to kindahow pass these information, but this has some drawbacks:
I can't use Get-Method,s since I'd need to pass this object via Body
Every method in every Controller needs to get this object passed
I (think I) can't use Dependency injection, since I need to pass this TFS-Parameter to the Layers behind the Controllers
Other approaches would all hurt the open closed principles I guess, since the Controller really doesn't know which concrete TFS is used.
Is there a good possibility to make such stuff work? If not, what would be the best case for such a scenario?
I can't use Get-Method,s since I'd need to pass this object via Body
The ModelBinder can bind from the URI.
Every method in every Controller needs to get this object passed
Or you let the user store it in the session with a call, and read it from the session in other calls.
I (think I) can't use Dependency injection, since I need to pass this TFS-Parameter to the Layers behind the Controllers
Why do you want to inject this?
You could create a POST endpoint that accepts a TfsConfiguration object and returns a token, such as a GUID, that is passed to GET endpoints via the URL or a custom header. The flow could be:
POST TfsConfiguraton to api/tfstoken, which returns the token
Routes which require the token have URLs of the form api/tfstoken/...
Due to limitations on the server side I need to build a self hosting web service in .NET...
I'm currently looking at HttpSelfHostServer but I'm very un-cool with it's magical construction of the controller, that seems to be, based on name alone and using only the default constructor.
For my tests I need to inject a value into the controller and using an IoC framework for this one usage where vanilla dependancy injection will suffice is over the top.
Is there any way I can do this with HttpSelfHostServer? or are there other, non-deprecated, self-hosting alternatives that give me control over my controller constructor calls.
The HttpSelfHostConfiguration instance that you need to provide to the HttpSelfHostServer constructor inherits the DependencyResolver property from the HttpConfiguration class. Hence, you can provide a custom dependency resolver as outlined here, for instance.
I was able to override IHttpControllerActivator in a unit test, I think it's similar to what you're trying to do.
e.g.
httpConfiguration.Services.Replace(typeof(IHttpControllerActivator),
Mock<IHttpControllerActivator>());
(there's more info. about services here)
I have a ViewModel class which I want to resolve via the unity ServiceLocator, but my viewModel requires a parameter to the constructor. The parameter's type is one of the entities in my application (a Customer object) rather than some service implementation. I know that coding against the Unitycontainer itself I can pass a paramater like this:
_container.Resolve<CustomerDetailViewModel>(new ParameterOverrides {{"customer", customer}});
but if I dont have direct access to the container I need to go via the ServiceLocator like this:
(CustomerDetailViewModel)ServiceLocator.Current.GetInstance<CustomerDetailViewModel>();
However using the second approach I have no way to pass in any parameters to the ServiceLocator. Is there any way this can be done? Is it "wrong" to get an instance of the Container from the ServiceLocator and then use that?
The problem is that you are trying to inject an entity (Customer in this case) into a class. Entities are short lived objects and they don't tend to be good candidates for being injected.
Instead of injecting a Customer, inject a ICustomerRepository service. You can register an ICustomerRepository implementation in the startup path of the application and this way you won't have to call the container directly, which makes the application design cleaner and the unit tests easier.
If you write a wrapper for the ServiceLocator you can hold the unity container within the wrapper and the expose an additional resolve method overload that takes the ParameterOverrides property. Then the method could use the unity container to do the resolution as per your first code snippet rather than the ServiceLocator code snippet.