resolving dependencies of registered instance in Castle Windsor - castle-windsor

I wonder if it's possible for Castle container to resolve dependency on instance when it is registered as follows:
var inst = Globals.Ribbons.TestRibbon;
this.container.Register(
Component
.For<TestRibbon>()
.Instance(inst)
);
long story short, i work on Excel addIn, using Castle.Windsor as IoC Container, where in some point interaction happens betwen custom Ribbon and CustomTaskPane, as Ribbon is instantiated and loaded by Excel, i have no way to register type and then resolve it with dependencies (or there is a way?)
I have two options to workaround, do some manual Property Injection or reference Container from inside of Ribbon, either way it feels awkward.
Is there a way to register instance with Castle container, so that it would automatically resolve dependencies on that instance?

Related

Resolving a dependency while supplying values for downstream dependencies

I've been running into endless problems attempting to use Windsor with Web API and injecting HttpRequestMessage into downstream dependencies of a controller. Since I've tried all the matching answers on Stackoverflow, I'd like to ask the question in a different way:
In Castle Windsor, how can I resolve a component instance while supplying a value for a downstream dependency? That is, the supplied value is required by a component that is required by the component being resolved.
For context, I'm trying to inject HttpRequestMessage so that I can use it to resolve the request context (primarily to resolve an absolute URL).
Edit I'd also like to point out that I don't currently have a dependency on Web Host / System.Web and I'd rather not change that.
A proper approach is to
Create IMyDesiredRouteParameterProvider
Implement it. Get the current request inside it and get the url
Register it and inject it in the desired dependent class via constructor.
I made myself such an implementation and I can say that this way it works fine. You can make Web.Infrastructure assembly and put the implementation there. Or put both the interface and the implementation there if you are going to reference it from another web module.
using System;
using System.Web;
namespace RouteParameterProvider
{
interface IMyRouteParameterProvider
{
string GetRouteParameter();
}
public class ControllerActionMethodRouteParameterProvider : IMyRouteParameterProvider
{
public string GetRouteParameter()
{
string Parameter = HttpContext.Current.Request.RequestContext.RouteData.Values["controller"] as string;
if (string.IsNullOrEmpty(Parameter))
{
throw new InvalidOperationException();
}
return Parameter;
}
}
}
You can get every possible thing that the Request Context contains from :
HttpContext.Current.Request.RequestContext
And it will be better if you rethink your design decision :
I need HttpRequestMessage to be regstered prior to creating each
instance of SomethingController so that it will be available down at
the LinkGenerator layer.
Containers are to be initialized at runtime and then used to resolve.
I need HttpRequestMessage to be regstered prior to creating each
instance of SomethingController so that it will be available down at
the LinkGenerator layer.
It sounds like you want to register an item with the container at runtime, post-startup. In general, this is not a good practice--registration should be a discrete event that happens when the app is fired up, and the container's state should not be changed during runtime.
Dependency Injection is about resolving service components, not runtime state--state is generally passed via methods (method injection). In this case it sounds like your LinkGenerator component needs access to the ambient state of the request.
I'm not that familiar with HttpRequestMessage, but this answer seems to show that it is possible to retreive it from HttpContext.Current. You could make this a method on your LinkGenerator class, or wrap this call in a separate component that gets injected into LinkGenerator (HttpRequestMessageProvider?). The latter would be my preferred method, as it allows LinkGenerator to be more testable.
Given the lack of a clean way of doing this and Web API not providing information as to the hosted endpoint beyond per-request context objects, I ended up injecting the base url from configuration.
Is this library by Mark Seemann the answer? In the description he writes explicitly :
This approach enables the use of Dependency Injection (DI) because the
request can be injected into the services which require it.
Then gives an example :
// Inside an ApiController
var uri = this.Url.GetLink(a=> a.GetById(1337));
By which you can then pass the URL down the road in the service that you have injected in the controller.
UPDATE :
Mark Seemann wrote about the same exact problem here:
"Because HttpRequestMessage provides the context you may need to
compose dependency graphs, the best extensibility point is the
extensibility point which provides an HttpRequestMessage every time a
graph should be composed. This extensibility point is the
IHttpControllerActivator interface:..."
This way you can pass request context information to a component deep in the object graph by getting from the HttpRequestMessage and passing it to the DI container.
Just take a look at the interface of IHttpControllerActivator.
The WEB API framework gets the IHttpControllerActivator through DependencyResolver. You probably already replaced it by your CastleWindsorDependencyResolver. Now you have to implement and register your HttpControllerActivator and register it.
When the WEB API framework gets IHttpControllerActivator from DependencyResolver (your Castle Windsor DR) and calls IHttpControllerActivator.Create() it will pass you the HttpRequestMessage. You can get your info from there and pass it to the your CastleDR before you call Resolve(typeof(MyController)) which will resolve the whole object graph - that means you will have MyHttpContextInfo to inject in your XYZComponent deep in the resolution stack.
This way tou are passing the arguments in the last possible moment but it is still possible. In Castle Windsor I make such passing of arguments though CreationContext.AdditionalArguments["myArgument"];.

PerWebRequest and Transient lifeStyles

Can someone please help me understand several things?
Do I still have to register PerRequestModule to use
LifeStylePerWebRequest? I use Castle.Windsor 3.2.0.0 and it seems
everything works without this module. I definetly remember that
there was an exception before that tells me "You forget to register
this module".
What "objects tracked by release policy" really
means? I use several Components with LifeStyleTransient but when I
Resolve one I get it in "objects tracked by release policy"
property, when I Resolve others I don't get them there.
How can I check the actual objects stored inside the container (and their
number)?
1) I guess since version 3.x PerRequestModule will be automatically registered by windsor.
2) An object will be tracked by windsor only if needed(for ex if its lifestyle is Transient and it implements IDisposable interface).
3) You can run unit tests checking for handlers or manually set a debug point once you registered all components and navigate with VS viewer container object: it has a property that lists all registered components.

Castle Windsor dependency injection to properties

I am trying to add something (I don't know what that something is) to Castle Windsor that will detect when I'm trying to create an instance of a class that derives from System.Activities.Activity, Windsor would inspect the properties of type InArgument<T> and resolve values for these arguments before returning the created instance to the callee.
What are the steps for doing something like this?
Basically, I would have something like this:
var someActivity = container.Resolve<SomeActivity>();
Then Windsor would detect that SomeActivity derives from Activity, it would inspect the properties of type InArgument<T> on SomeActivity and would resolve values for those properties from the container itself.
But SomeActivity could be any Activity, not necessarily specifically SomeActivity.
Windsor by default sets all the properties it can resolve.

Castle Windsor - Register compoents before my Facilities load. - Delay loading configuration file?

I would like to register some components in my Windsor container before my Facilities load - (so that I can use some the components in the facilities)
I was thinking there should be some way to initialize windsor without a configuration file, register some components, and only then load the configuration? - this would result in that my configured facilities would load only after I registered my components.
For example:
var container = new WindsorContainer();
//Register a custom component, which will be used in some of the facilities
container.Register(Component.For<IMyService>().ImplementedBy<MyService>());
//Now load via the configuration - unfortunately the method "Configure" doesn't exist
container.Configure(new XmlInterpreter(new ConfigResource("castle")));
Appreciate any help on this,
Thanks!
container.Install(Configuration.FromAppConfig());
See the documentation.

How to get instance of service in Windsor Castle

In a multilayer application (ASP MVC: UI project, DAL project) i registered in web.config the components.
Now i have this problem: Unit of Work pattern has do be implemented and i need to get the current instance of a particular service. The registration of the services happened in the UI project, but i need to get the current instance of this service in the DAL project. How do i get this reference?
In the UI project i already needed a way to get something resolved:
container = new WindsorContainer(
new XmlInterpreter(new ConfigResource("castle"))
);
personRepository= container.Resolve<IPersonRepository>();
Would it be OK to use the same technique in the DAL project? If yes, should i write the configuration in a separate file, so that it can be accessed by all the layers(projects)?
Sorry for this (i think) naive question but it's my first project using Castle and i think i don't understand the big picture of it!
Code snippet would help a lot.
Thanks in advance!
In a nutshell: one container instance per application, one container configuration that has all the components you need for the application. If you need a service in your DAL, inject the appropriate service interface in your DAL class via constructor (if the dependency is required) or setter (if the dependency is optional).
Try really hard to avoid using a static IoC gateway, it hides the true dependencies of a component and it hampers testability.
See these related questions:
Usage of IoC Containers; specifically Windsor
Is it correct to have many Castle Windsor containers per application if those containers belong to different tiers?
Have a look at this article. It shows you how to write a static class that performs dependency resolution using Castle Windsor. You should consider putting this class in a separate project that can be referenced from both your UI and DAL projects to allow code reuse. As the article explains, your class should provide a bootstrapper facility that initializes your IoC container. In your case, this would look like:
public static class IoC
{
private WindsorContainer _container;
public static void Initialize()
{
_container = new WindsorContainer(
new XmlInterpreter(new ConfigResource("castle"))
);
}
}
The bootstrapper would be invoked from the application startup event in your UI projects Global.asax file.
The other methods for obtaining instances of objects from the container would be as per the article.