Is there possibility to configure Interceptor to hook methods only of special interface, or by base class?
Currently I have registered Interceptor that works with scope of connections to one DB. Now I added another scope working with another db and want to add another interceptor, which will hook methods of second scope. It is possible to configure interceptor via xml files, instead of checking target of invocation properties.
I've added interceptor via components:
<component
type="Common.IoC.SessionScopeInterceptor, Common"
lifestyle="transient">
</component>
AFAIK this interceptor intercepts all methods of all classes registered in windsor container.
I wand to add something like this^
<component
type="Common.IoC.SessionScopeInterceptor, Common"
lifestyle="transient"
interceptOnlyVirtualMethods="true"
interceptClass="Common.IoC.SessionScope1, Common"
>
</component>
you need to create your own AbstractFacility that implements your desired behaviour. Essentially, you need to implement something similar to what Mikael Sundberg did in the answer to this question.
Related
The Spring ResponseBodyAdvice allows for handling the JSON-Response. I want to write it to the logger but by this would also like to add the name of the RestController being invoked in this transaction.
Can anyone tell, whether the classname is somewhere available in the parameters of the instance of ResponseBodyAdvice.
Got it. The parameter "MethodParameter" supplied to the "beforeBodyWrite"-method contains the attribute "containingClass" which provides the name of the intended Controller (I found this with testing - did not find any docs about the use of this attribute until now). That will do for me
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"];.
I'm using NServiceBus (3.2.2), RavenDB (1.2.2017-Unstable) and Windsor (3.0.0.4001) in an MVC 4 project.
I have a IHandleMessages class that handles 3 different messages, and that needs an IDocumentSession, and therefore defines a property such as:
public IDocumentSession DocumentSession { get; set; }
I've copied the RavenDbUnitOfWork implementation from NServiceBus' website
I've registered IDocumentStore, IDocumentSession and IManageUnitsOfWork in my Windsor container as follow:
container.Register(
Component
.For<IManageUnitsOfWork>()
.ImplementedBy<RavenUnitOfWork>()
.LifestyleTransient()
);
container.Register(
Component
.For<IDocumentStore>()
.UsingFactoryMethod(k => DocumentStoreHolder.DocumentStore)
.LifestyleSingleton(),
Component
.For<IDocumentSession>()
.UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession())
.LifestyleTransient()
);
NServiceBus is configured to use my container:
Configure.With()
.CastleWindsorBuilder(container);
I'm encountering the problem that the UnitOfWork and the message handler receive different instances of the DocumentSession. This means that objects stored in the session in the message handler are not saved, since SaveChanges() is called on a different DocumentSession.
Removing the Transient lifestyle causes different kind of problems, that result in concurrency/conflicts when updating objects from RavenDb, since (probably) the message handler keeps getting the same instance of the DocumentSession, which holds a cached version of the updated object.
Update:
As suggested, I've tried changing the registration of the IDocumentSession in Windsor, to the Scope lifestyle, like this:
Component
.For<IDocumentSession>()
.UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession())
.LifestyleScope()
This causes exceptions when the container tries to resolve the MVC Controller, saying that the scope was not found, and asking if I forgot to call BeginScope().
You need to have a scope of Per Message, not transient or singleton.
I am assuming that your mvc controller has a direct dependency on the IDocumentStore. You need to call container.BeginScope() before each request from the web. You can either do this as an action filter attribute http://msdn.microsoft.com/en-us/library/system.web.mvc.actionfilterattribute.aspx or as an AOP aspect on the controller itself http://cangencer.wordpress.com/2011/06/02/asp-net-mvc-3-aspect-oriented-programming-with-castle-interceptors/.
The issue is you need different lifestyles when using nservicebus in an asp.net mvc website when sharing the IDocumentSession in the same container.
For ASP.NET MVC you need a PerWebRequest lifestyle and for NServiceBus you need the Scoped lifestyle.
To do that i've used the hybrid lifestyle code in the castle contrib project:
https://github.com/castleprojectcontrib/Castle.Windsor.Lifestyles/tree/master/Castle.Windsor.Lifestyles
When calling from an ASP.NET context, it uses the WebRequestScopeAccessor. For NServicebus you need the LifetimeScopeAccessor. This is not in the contrib project, but is easy to add:
public class HybridPerWebRequestLifetimeScopeScopeAccessor : HybridPerWebRequestScopeAccessor
{
public HybridPerWebRequestLifetimeScopeScopeAccessor()
: base(new LifetimeScopeAccessor())
{
}
}
And in your registration code you need something like:
container.Register(Component.For<IDocumentSession>().LifestyleScoped<HybridPerWebRequestLifetimeScopeScopeAccessor>().UsingFactoryMethod(() => RavenDbManager.DocumentStore.OpenSession()));
And here's an implementation for Rhino Service Bus i used before switching to nservicebus:
https://gist.github.com/4655544
I am starting developing with Symfony2 framework and I like to use the Eventdispatcher. Now I have three questions I could find an answer with google yet.
Where I place the dispatcher so it is accessable from everywhere in
tha app?
How I can configure customevents? Should I place all in one file or
one for each bunble?
How much effort is it to configure it with annotations, i.e
#Event("some.event")? Is that possible?
General
I might suggest the Symfony 2 documentation on the EventDispatcher as a good starting point, assuming that you mean you wish to provide custom events rather than a custom event dispatcher.
Symfony2 Internals - The Event Dispatcher
Location of Events
In terms of location, an 'Event' folder within the appropriate bundle is a good choice. It is likely that the actual dispatching of the event will take place only within the bundle context, whereas listeners may reside elsewhere. This is however a separate topic and of minimal relevance as they simply subscribe to the event's string-name (e.g., 'store.order' to borrow the documentation's example) and only require knowledge of the Event's interface/type.
So you might have an Event called 'Foo' within the 'Bar' bundle in 'Zap' namespace:
namespace Zap\Bar\Event;
use Symfony\Component\EventDispatcher\Event;
class FooEvent extends Event
{
// ...
}
When you then come to dispatch an event from within your bundle, you might choose to use the event identifier 'zap.bar.foo', and of course you can then register listeners from elsewhere to be notified on this identifier as you see fit.
Accessing the Event Dispatcher
Where you wish to access the primary EventDispatcher instance, acquire access to the Dependency Injection Container and retrieve the 'event_dispatcher' service. A simple approach is to have your class extend 'ContainerAware' and then retrieve the dispatcher with
$dispatcher = $this->container->get('event_dispatcher');
To answer your first question:
Where I place the dispatcher so it is accessable from everywhere in tha app?
Actually, there is already preconfigured event dispatcher service accessible, as #jstephenson pointed out, by calling $dispatcher = $this->container->get('event_dispatcher'); so you don't have to create your own instance anywhere.
However, if you need your own event dispatcher, you can simply configure it in your services configuration file (i.e. services.xml) of your bundle like this:
<service id="my_dispatcher" class="Symfony\Component\EventDispatcher\EventDispatcher" />
You can of course use your own dispatcher class as long as it implements EventDispatcherInterface.
I'm trying to implement automatic registration of my listeners to a singleton event aggregator when listeners are created by the IoC container - basically what Jeremy D. Miller is doing, but with Castle instead of StructureMap.
So I want to be able to "intercept" Windsor's object creation mechanism and, if the object supports the marker interface (let's say IListener), call the Subscribe method to an EventAggregator (which is also registered in the container) to make the newly created object a subscriber to events. Also, before the object instance has been released by the container, I want to be able to unsubscribe it.
I'm a little bit confused about what mechanism in Windsor Castle I should use to achieve something like this? I started looking at IInterceptor interface, but it seems to intercept all calls to the object, which is not what I really need (and want to avoid for performance reasons).
IKernel exposes various events like ComponentCreated and ComponentDestroyed which you can use to build that. There are many samples on the web.
Otherwise you could just use the event wiring facility, but it's not convention based.
You could also use OnCreate like this:
container.Register(
Component.For(typeof (Foo)).OnCreate(
(k, c) => {
// ...
eventAggregator.Subscribe(c);
// ...
}));