Registering an Interceptor For All Interface Implementations in Castle Windsor - castle-windsor

I'm fairly new to Castle Windsor and in particular using Interceptors and am wondering if it is possible to register an Interceptor across all implementations of a particular interface without specifying each implementation in turn. For example, I have an interface called IComponent which will be implemented by a number of classes. I have a ComponentInterceptor class written to act on these classes when they have executed a particular method. I would like to do something like:
_container.Register(
Component.For<IComponent>()
.Interceptors("ComponentInterceptor")
.LifestyleSingleton())
Rather than having to do:
_container.Register(
Component.For<IComponent>()
.ImplementedBy<ComponentA>()
.Interceptors("ComponentInterceptor")
.LifestyleSingleton()),
_container.Register(
Component.For<IComponent>()
.ImplementedBy<ComponentB>()
.Interceptors("ComponentInterceptor")
.LifestyleSingleton())

I found another approach, I wanted to register this interceptor for all components being registered and do this hopefully minimal fuss. To do this I follow this article and created a new class like this:
public class MyContributeComponentConstruct : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
if (model.Services.Any(s => s == typeof(IComponent)))
{
model.Interceptors.Add(InterceptorReference.ForType<ComponentInterceptor>());
}
}
}
and then add this contribute with the Castle Windsor container
container.Kernel.ComponentModelBuilder.AddContributor(new MyContributeComponentConstruct ());

You can register components in the container using conventions via the Classes class. The following registers all classes in the current assembly that implement IComponent under the service IComponent and with your ComponentInterceptor interceptor:
container.Register(
Classes.FromThisAssembly()
.BasedOn<IComponent>()
.WithService.FromInterface()
.Configure(c => c.Interceptors<ComponentInterceptor>())
);
The Windsor documentation provides a bunch of other examples and explains in detail what different classes are for.

Related

Cannot register the component in castle windsor

I have used the below link for the castle windsor dependency injection.I am not able to register the component.
http://www.codeproject.com/Tips/1052382/ASP-NET-MVC-Dependency-Injection-using-Windsor#_comments
public class ServiceInstaller : IWindsorInstaller
{
public void Install(Castle.Windsor.IWindsorContainer container,
Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
{
container.Register(
Component.For<Interfaces.TestInterface>()
.ImplementedBy<Services.TestServices>()
.LifestyleTransient());
}
}
ErrorMessage:
An exception of type
'Castle.MicroKernel.ComponentRegistrationException' occurred in
Castle.Windsor.dll but was not handled in user code
Additional information: Component
TestForCastleWindsor.Services.TestServices could not be registered.
There is already a component with that name. Did you want to modify
the existing component instead? If not, make sure you specify a unique
name.
That component is being registered twice. This can happen when IWindsorInstaller implementations or components are picked up by convention. For example, all assemblies in a directory are scanned for implementations of IWindsorInstaller and an old duplicate assembly is present. Or all implementations of another interface also implemented by your component are previously registered.

Managing RavenDb session in Windsor under NServiceBus

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

Castle Windsor equivalent to WhenClassHas from ninject

I'm trying to convert some applications that use Ninject to Castle Windsor so that I can eliminate some dependencies.
I can't figure out how to achieve some of Ninject's functionality using the container.Register methods in windsor.
Namely (in Ninject):
Kernel.Bind<ISessionProvider>().To<UnitOfWorkSessionProvider>();
Kernel.Bind<ISessionProvider>().To<ThreadSafeSessionProvider>()
.WhenClassHas<RequireThreadSafeSession>();
This tells Ninject that when building a class that has ISessionProvider in the constructor, use UnitOfWorkSessionProvider, unless it has the attribute RequireThreadSafeSession, in which case it is given a ThreadSafeSessionProvider.
Question one- can this be done in Windsor? The documentation is a bit confusing.
Question two- how does one do this? It seems like conditional binding is permitted in the AllTypes configuration class, but the usage patterns are not quite as transparent
You can use UsingFactoryMethod in the registration API to use late-binding and decide on the implementation. Try this:
container.Register(Component.For<ThreadSafeSessionProvider>());
container.Register(Component.For<UnitOfWorkSessionProvider>());
container.Register(Component.For<ISessionProvider>().UsingFactoryMethod((x, u) => FindImpl(x, u)));
container.Register(Component.For<ClassUnderTest>());
private ISessionProvider FindImpl(IKernel kernel, CreationContext context)
{
var classUnderTest = context.Handler.ComponentModel.Implementation;
if (classUnderTest.HasAttribute<IsThreadSafeAttribute>())
{
return kernel.Resolve<ThreadSafeSessionProvider>();
}
return kernel.Resolve<UnitOfWorkSessionProvider>();
}

Castle Windsor inject types dynamically based on attributes or config file

I have an idea to design something like this. My class can accept a sequence of exception handlers that are registered when an instance of the class is created.
class Foo {
public Foo (IEnumerable<UnhandledExceptionEventHandler> handlers) {
foreach(var handler in handlers) {
AppDomain.CurrentDomain.UnhandledException += handler;
}
}
}
Now, I'd like to do something like this. I want to have Castle Windsor inject the handlers for me either based on attributes applied to the class
[LogExceptions(typeof(SomeExceptionHandler), typeof(AnotherExceptionHandler))]
class Foo { // code }
or specified in a config file. So in the former example, when Castle Windsor wants to resolve an instance of Foo, it would look at the LogExceptions attribute and see that it needs to construct Foo via
new Foo(new[] { new SomeExceptionHandler(), new AnotherExceptionHandler() });
What are the concepts in Castle Windsor that I want to look at that will enable me to solve this problem?
If my design is retarded, please say so but offer constructive ideas! Thanks!
The best extension point for stuff like that is ComponentModel construction contributors. You will need to discover what handlers apply to your component, and then construct an array of service override dependencies for them.

Castle Windsor Typed Factory Facility equivalents

do any other .NET IoC containers provide equivalent functionality to the typed factory facility in Castle Windsor?
e.g. if I am using an abstract factory pattern in a WPF application:
public class MyViewModel
{
private IAnotherViewModelFactory factory;
public void ShowAnotherViewModel()
{
viewController.ShowView(factory.GetAnotherViewModel());
}
}
I don't want to have to create a manual implementation of IAnotherViewModelFactory for every type of ViewModel I wish to show, I want the container to take care of this for me.
AutoFac has a feature called Delegate Factories, but as far as I can tell, it works only with delegates, and not interfaces.
I haven't encountered anything similar to Castle's Typed Factory Facility in neither StructureMap nor Unity, but that doesn't necessarily mean that they're not there...
The only way I can imagine that something like this could be implemented for interfaces is via a dynamic proxy. Since Castle Windsor has a Dynamic Proxy, but few other containers have anything similar, this might go a long way to explain why this feature isn't ubiquitous.
Unity also offers interception capabilities, so it must have some sort of dynamic proxy implementation, but I'm pretty sure it doesn't have anything equivalent to Typed Factories. Compared to other containers, Unity is rather basic.
In Autofac you can implement typed factories on top of the delegate approach Mark mentions. E.g.
class AnotherViewModelFactory : IAnotherViewModelFactory {
Func<AnotherViewModel> _factory;
public AnotherViewModelFactory(Func<AnotherViewModel> factory) {
_factory = factory;
}
public AnotherViewModel GetAnotherViewModel() {
return _factory();
}
}
If this class is registered with the container, along with AnotherViewModel Autofac will provide the Func<AnotherViewModel> implementation implicitly:
builder.RegisterType<AnotherViewModel>();
builder.RegisterType<AnotherViewModelFactory>()
.As<IAnotherViewModelFactory>();
Practically any interface you can implement using Typed Factory Facility can be implemented in Autofac using this kind of approach. The primary difference is that the Windsor implementation configures the factory through the component registration API, while in Autofac the factory is a component in its own right.
For more sophisticated examples you might like to look at: http://code.google.com/p/autofac/wiki/RelationshipTypes and http://nblumhardt.com/2010/01/the-relationship-zoo/.
I have recently implemented an equivalent of Castle Windsor Typed Factories for Unity. You can find the project at https://github.com/PombeirP/Unity.TypedFactories, and the NuGet package at http://nuget.org/packages/Unity.TypedFactories.
The usage is the following:
unityContainer
.RegisterTypedFactory<IFooFactory>()
.ForConcreteType<Foo>();
The parameter matching is done by name, which is fine for my needs, although the library could easily be extended to support other needs.