Intercepting singleton instances - castle-windsor

I'm receiving "Potential Lifestyle Mismatches"
Component 'MyComponent' with lifestyle Singleton depends on
'Castle.TypedFactory.Interceptor' with lifestyle Transient
Is there any issue using an Interceptor against multiples singletone instances?
,Component.For<ApiInterceptor>()
, AllTypes.FromAssemblyContaining<MyServiceContract>()
.Where(Component.IsInSameNamespaceAs<MyServiceContract>())
.Configure(c => c.Interceptors(typeof(ApiInterceptor)))
.Configure(c => c.LifeStyle.Singleton)

It's probably fine. There's a reason why this diagnostics is called potential lifestyle mismatches.

Related

Castle Windsor releasing of Transient component in WCF service

I'm using Castle Windsor with my WCF service (hosted using console application).
This is my configuration:
container.AddFacility<WcfFacility>().
Register(Component.For<IService>().
ImplementedBy<MyService>().LifeStyle.Transient.
AsWcfService(new DefaultServiceModel().
AddBaseAddresses("someURI").
AddEndpoints(WcfEndpoint.BoundTo(new BasicHttpBinding())).
PublishMetadata(o => o.EnableHttpGet())));
I chose Transient lifestyle for my service and some of this service dependencies are also Transients. As I understand after reading the documentation and some blogs if you have component with lifestyle Transient you should be responsible for releasing it.
Where should I release my transient component? Is this my responsibility or maybe the WcfFacility take care for that somehow?
What is the difference between Transient and PerWcfSession lifestyle
(btw what is the different between PerWcfSession and PerWcfOperation isnt each operation called on WCF service have its own session?)
You have the responsibility to release any component that you resolve directly from the container. So you never release subdependencies of a component that you resolve.
Since in this case the wcf service is resolved for you by the facicility, you don't need to release anything. The facility will take care.
If you register as PerWcfCall you will get one component per wcf call. If you use transient than everytime you have a subdependency of that type you will get a new instance.

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

Register additional component implementations for a service at runtime in Castle Windsor

Using Castle Windsor I can register multiple implementations of a type e.g.
container.Register(Component.For<IMyInterceptor>()
.ImplementedBy<MyInterceptor>();
container.Register(Component.For<IMyInterceptor>()
.ImplementedBy<MyInterceptor2>();
This all works as you'd expect and I can resolve multiple implementations using ResolveAll()
If I try to register an instance of another implementation at runtime though - e.g.
var interceptor = new MyInterceptor3();
Container.Register(
Component.For<IMyInterceptor>()
.Instance(interceptor));
I get an exception:
There is a component already registered for the given key MyInterceptor3
Is this the expected behaviour? What I'm trying to acheive is to use e.g. Container.ResolveAll() to get a list of default implementations of IMyInterceptor plus optional additional implementations (i.e. on a request by request basis, when debug modes are enabled).
This will sort you out.
var interceptor = new MyInterceptor3();
Container.Register(
Component.For<IMyInterceptor>()
.Instance(interceptor).Named("something unique));
Names must be unique.

Windsor Dependency Injection Problem with generics

I have an Interface IRepo <Entity>. I have a generic implementation Repo<Entity>.
Now i just do the following
Container.Register(AllTypes.FromAssemblyNamed("assemblyname").Pick()
.WithService.DefaultInterface()
.Configure(c => c.LifeStyle.PerWebRequest))
and register all the interface with respective implementations. This seems to work fine.
My Problem arises when i try to be more specific.
If i try to map IRepo<Person> with Person being a class subclassing Entity with <UserRepo> using
Container.Register(Component.For(IRepo<Person>).ImplementedBy(UserRepo).LifeStyle.PerWebRequest);
It does not seem to work.
The order in which i am doing this is that i am registering this specific implementation and then loading and registering all the interfaces to types from the assembly.
It does not seem to work.
DefaultInterface doesn't support generics. You can use AllInterfaces instead or a custom strategy via Select method

Windsor Castle: Hooking up to container's resolving and releasing mechanism

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);
// ...
}));