How to register an interface for interceptions - castle-windsor

I want to register an interface like: IInterceptingAware, so that for all classes which implement this interface an interceptor class is used.
public class InterceptorClass : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// Do my work
}
}
public class Foo : IInterceptingAware
{
}
public class Bar : IInterceptingAware
{
}
How do I setup castle windsor for this?

using (var container = new WindsorContainer())
{
container.Register(
Component.For<MyInterceptorClass>(),
Classes.FromThisAssembly()
.BasedOn<IInterceptingAware>()
.WithServiceDefaultInterfaces()
.ConfigureFor<IInterceptingAware>(c => c.Interceptors<MyInterceptorClass>())
);
var foo = container.Resolve<Foo>();
foo.Test();
var bar = container.Resolve<IBar>();
bar.Test();
}
Console.ReadLine();
Keep in mind interceptor requires at least virtual methods on target class, even better your target class should implement an interface in order to have the interceptor working on that contract.
Said so, your Foo class should at least have a method named Test marked as virtual
while Bar should implement IBar:
public interface IBar
{
void Test();
}

Related

Castle Windsor, selecting service implementation depending on some context parameters

With Castle Windsor 3.2
I need to resolve service implementation on the fly depending on contextual parameters.
Here is basic example of what I want to do:
I have a service IFoo
public interface IFoo
{
object GetSomething();
}
Implemented by 2 different classes Foo1 and Foo2
public class FooBase
{
public int Number {get; private set;}
public FooBase(int number)
{
Number = number;
}
}
public class Foo1 : IFoo
{
public Foo1(int number):base(number)
public object GetSomething()
{
return "Foo1";
}
}
public class Foo2 : IFoo
{
public Foo2(int number):base(number)
public object GetSomething()
{
return "Foo2";
}
}
I want to call the castle windsor resolve method with number as parameter, and depending on the number I want to have Foo1 or Foo2 object:
var foo1 = container.Resolve<IFoo>(new {number= 1});
// foo1 is Foo1
var foo2 = container.Resolve<IFoo>(new {number= 2});
// foo2 is Foo2
I tried several potential solutions, but I'm realy confused because of the lack of Castle Windsor documentation and examples, adding to that most of the examples are not up to date and are using obsolete API.
So I have seen some example using the following concepts, but none of them seemed to much my requirement :
HandlerSelector
Typed Factory facility
UsingFactoryMethod
Here is the code that worked for me:
container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<IFoo>().ImplementedBy<Foo1>().Named("Foo1"),
Component.For<IFoo>().ImplementedBy<Foo2>().Named("Foo2"),
Component.For<IFooFactory>().AsFactory(c => c.SelectedWith<FooSelector>())
);
Create a Foo factory :
public interface IFooFactory
{
IFoo CreateFoo(int number);
}
and a selector:
public class FooSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(System.Reflection.MethodInfo method, object[] arguments)
{
var argument = (int) arguments[0];
return string.Format("Foo{0}", argument);
}
}
use the following registration code:
container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<FooSelector>,
Component.For<Foo1>(),
Component.For<Foo2>(),
Component.For<IFooFactory>().AsFactory(c => c.SelectedWith<FooSelector>())
);
Create a Foo factory :
public interface IFooFactory
{
IFoo CreateFoo(int number);
}
and a selector:
public class FooSelector : DefaultTypedFactoryComponentSelector
{
protected override Type GetComponentType(System.Reflection.MethodInfo method, object[] arguments)
{
var argument = (int) arguments[0];
if (argument == 1) return typeof (Foo1);
if (argument == 2) return typeof(Foo2);
throw new ApplicationException();
}
}
Now resolve the IFooFactory and call the create methode with the value that you want.
Kind regards,
Marwijn.

registering open generic decorators for typed implementations in castle windsor

While trying to coerce Windsor into wrapping an implementation with a random number of decorators, i've stumbled upon the following:
i have 3 decorators and an implementation all using the same interface.
if you run this code, windsor resolves icommandhandler<stringcommand> as implementation, which, as far as i can tell, is expected behaviour, because the typed implementation can not be registered with the open typed decorators.
However, if you uncomment the line container.Register(Component.For<ICommandHandler<stringCommand>>().ImplementedBy<Decorator1<stringCommand>>());, all three decorators will be used to resolve implementation, which is the desired result (sort of : ).
class Program
{
static void Main(string[] args)
{
var container = new WindsorContainer();
container.Register(Component.For(typeof(ICommandHandler<>)).ImplementedBy(typeof(Decorator1<>)));
container.Register(Component.For(typeof(ICommandHandler<>)).ImplementedBy(typeof(Decorator2<>)));
container.Register(Component.For(typeof(ICommandHandler<>)).ImplementedBy(typeof(Decorator3<>)));
//uncomment the line below and watch the magic happen
//container.Register(Component.For<ICommandHandler<stringCommand>>().ImplementedBy<Decorator1<stringCommand>>());
container.Register(Component.For<ICommandHandler<stringCommand>>().ImplementedBy<implementation>());
var stringCommandHandler = container.Resolve<ICommandHandler<stringCommand>>();
var command = new stringCommand();
stringCommandHandler.Handle(command);
Console.WriteLine(command.s);
Console.ReadKey();
}
}
public interface ICommandHandler<T>
{
void Handle(T t);
}
public class stringCommand
{
public string s { get; set; }
}
public abstract class Decorator<T> : ICommandHandler<T>
{
public abstract void Handle(T t);
};
public class Decorator1<T> : Decorator<T>
where T : stringCommand
{
private ICommandHandler<T> _handler;
public Decorator1(ICommandHandler<T> handler)
{
_handler = handler;
}
public override void Handle(T t)
{
t.s += "Decorator1;";
_handler.Handle(t);
}
}
public class Decorator2<T> : Decorator<T>
where T : stringCommand
{
private ICommandHandler<T> _handler;
public Decorator2(ICommandHandler<T> handler)
{
_handler = handler;
}
public override void Handle(T t)
{
t.s += "Decorator2;";
_handler.Handle(t);
}
}
public class Decorator3<T> : Decorator<T>
where T : stringCommand
{
private ICommandHandler<T> _handler;
public Decorator3(ICommandHandler<T> handler)
{
_handler = handler;
}
public override void Handle(T t)
{
t.s += "Decorator3;";
_handler.Handle(t);
}
}
public class implementation : ICommandHandler<stringCommand>
{
public void Handle(stringCommand t)
{
t.s += "implementation;";
}
}
Why exactly is this happening, is this a feature of windsor that i am not aware of? Is there perhaps a different way to achieve the same effect? (without resorting to reflection)
When windsor tries to resolve a component it will first try to resolve the more specific interface. So when you register Component.For it will prefer to resolve this over an open generic type.
If the same interface is registered multiple times, it will use the first one specified.
So if you don't uncommment the line your application will resolve implementation since this is the most specific component.
If you do uncomment the line decorator1 will be resolved and indeed the magic starts. The decorator will now start looking for the first registered component that satisfies it's constructor, in this case that would be decorator1 again (you did notice that your output show decorator1 2 times ?). Which will the resolve the next registered component and so on till it comes to the actual implementation.
So the only thing I can think about is not registering decorator1 as an open generic but as a specific type.
Kind regards,
Marwijn.

Change ServiceOverride after component registration in Castle

I have two components registered for a service:
container.Register(
Component.For<IDataStorage>().Named("FirstChoice").ImplementedBy...
Component.For<IDataStorage>().Named("SecondChoice").ImplementedBy
Then I have a set of components deriving from this base class, that depends on those components:
public abstract class BaseMessageHandler
{
public IDataStorage FirstStorage {get; set;}
public IDataStorage SecondStorage {get; set;}
}
If I was registering these "handlers" (deriving from BaseMessageHandler) manually, I would specify a service override, indicating which component I want for properties "FirstStorage" and "SecondStorage". Something like:
.Configure(x => x.DependsOn(
ServiceOverride.ForKey("FirstStorage").Eq("FirstChoice"),
ServiceOverride.ForKey("SecondStorage").Eq("SecondChoice"))
Unfortunately, this registration is done automatically by a framework (NServiceBus). I know that if I register the handlers first (before NServiceBus has a chance to do so), these registrations will stick. But rather than try to guess and mimick the registration NServiceBus does, I wonder if I can specify service overrides in a custom IContributeComponentModelConstruction.
It seems a good place to do so, and I'm able to find these properties:
public class DataStorageOverrideContributor : IContributeComponentModelConstruction
{
public void ProcessModel(Castle.MicroKernel.IKernel kernel, Castle.Core.ComponentModel model)
{
var dataStorageDependencies = model.Properties.Where(
x => x.Dependency.TargetItemType == typeof(IDataStorage));
foreach (var propertyDependency in dataStorageDependencies)
{
// now what??
but I'm not sure the proper way to:
check if a service override is already specified (in which case I would do nothing)
add a service override to a property dependency.
Is this something that could be done inspecting and working the ComponentModel in the IContributeComponentModelConstruction.ProcessModel method?
I would use a subdependency resolver in your scenario. You can see the code below on how to use it.
Goodluck,
Marwijn.
public interface IDataStorage
{
}
public class DataStore1 : IDataStorage
{
}
public class DataStore2 : IDataStorage
{
}
public class BaseMessageHandler
{
public IDataStorage FirstStorage { get; set; }
public IDataStorage SecondStorage { get; set; }
}
public class SubDependencyResolver : ISubDependencyResolver
{
private readonly IKernel _kernel;
public SubDependencyResolver(IKernel kernel)
{
_kernel = kernel;
}
public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
DependencyModel dependency)
{
return model.Implementation == typeof (BaseMessageHandler) && dependency.TargetType == typeof(IDataStorage);
}
public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
DependencyModel dependency)
{
var handlers = _kernel.GetHandlers(dependency.TargetType);
switch (dependency.DependencyKey)
{
case "FirstStorage":
return handlers.Single(h => h.ComponentModel.Implementation == typeof (DataStore1)).Resolve(context);
case "SecondStorage":
return handlers.Single(h => h.ComponentModel.Implementation == typeof(DataStore2)).Resolve(context);
}
return null;
}
}
[TestFixture]
public class Tests
{
[Test]
public void SomeTest()
{
var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new SubDependencyResolver(container.Kernel));
container.Register(
Component.For<IDataStorage>().Named("FirstChoice").ImplementedBy<DataStore1>(),
Component.For<IDataStorage>().Named("SecondChoice").ImplementedBy<DataStore2>(),
Component.For<BaseMessageHandler>()
);
var messageHandler = container.Resolve<BaseMessageHandler>();
Assert.AreEqual(typeof(DataStore1), messageHandler.FirstStorage.GetType());
Assert.AreEqual(typeof(DataStore2), messageHandler.SecondStorage.GetType());
}
}
alternative you may use:
case "FirstStorage":
return handlers.Single(h => h.ComponentModel.Name == "FirstChoice").Resolve(context);
case "SecondStorage":
return handlers.Single(h => h.ComponentModel.Name == "SecondChoice").Resolve(context);
to resolve on component name rather then implementation type.

Have Castle Windsor select component based on requestor type namespace

I have an interface ISession whose instance is produced by a different Session Factory depending on which namespace the class belongs to.
Example of my component registration:
IWindsorContainer container = new WindsorContainer();
container.Register(Component.For<NHibernate.ISession>()
.UsingFactoryMethod((kernel, creationContext) =>
{
NHibernate.ISession session =
new SessionFactoryForNamespace1()
.Instance.GetSession();
return session;
})
.LifestylePerWebRequest());
container.Register(Component.For<NHibernate.ISession>()
.UsingFactoryMethod((kernel, creationContext) =>
{
NHibernate.ISession session =
new SessionFactoryForNamespace2()
.Instance.GetSession();
return session;
})
.LifestylePerWebRequest());
container.Register(Component.For<Namespace1.IRepository1()
.ImplementedBy<Namespace1.Repository1>());
container.Register(Component.For<Namespace2.IRepository2>()
.ImplementedBy<Namespace2.Repository2>());
Example of the resolution graph:
public class MyController
{
public MyController(Namespace1.IRepository1 repo1,
Namespace2.IRepository2 repo2) { }
}
namespace Namespace1
{
public interface IRepository1 { }
public class Repository1 : IRepository1
{
public Repository1(NHibernate.ISession session) { }
}
}
namespace Namespace2
{
public interface IRepository2 { }
public class Repository2 : IRepository2
{
public Repository2(NHibernate.ISession session) { }
}
}
When Castle Windsor is asked to resolve MyController, it then tries to resolve IRepository1 and IRepository2, and subsequently the ISession for each. I want to have Castle Windsor select the component handlers based on the requestor type's namespace which in my example is either Namespace1 or Namespace2.
I am new to Castle Windsor and not sure where in the resolution pipeline I'm supposed to be plugging into.
What is the best approach to accomplish what I have outlined above?
I think a service override would work for this.
UPDATE:
I also did an article on some of Windsor's advanced features (including a section on Service Overrides) that should augment the documentation linked above.
Here is how I implemented service override solution:
Repository interfaces now inherit from a common repository interface:
public class MyController
{
public MyController(Namespace1.IRepository1 repo1,
Namespace2.IRepository2 repo2) { }
}
public interface IRepository { }
namespace Namespace1
{
public interface IRepository1 : IRepository { }
public class Repository1 : IRepository1
{
public Repository1(NHibernate.ISession session) { }
}
}
namespace Namespace2
{
public interface IRepository2 : IRepository { }
public class Repository2 : IRepository2
{
public Repository2(NHibernate.ISession session) { }
}
}
Repository component registeration based on its namespace:
IWindsorContainer container = new WindsorContainer();
...
Action<Type> RegisterRepository = t =>
{
container.Register(
AllTypes.FromAssemblyContaining(t)
.BasedOn(typeof(IRepository))
.WithServiceAllInterfaces()
.Configure(c =>
{
c.DependsOn(
ServiceOverride
.ForKey<NHibernate.ISession>()
.Eq(c.Implementation.Namespace));
c.LifeStyle.Is(LifestyleType.Transient);
})
);
};
RegisterRepository(typeof(Namespace1.IRepository1));
RegisterRepository(typeof(Namespace2.IRepository2));
Seems to work :)

Run code before class instanciation in ActionScript 3

I need to run code in a class declaration before its instanciation. This would be especially useful to automatically register classes in a factory. See:
// Main.as
public class Main extends Sprite
{
public function Main() : void
{
var o : Object = Factory.make(42);
}
}
// Factory.as
public class Factory
{
private static var _factory : Array = new Array();
public static function registerClass(id : uint, c : Class) : void
{
_factory[id] = function () : Object { return new c(); };
}
public static function make(id : uint) : Object
{
return _factory[id]();
}
}
// Foo.as
public class Foo
{
// Run this code before instanciating Foo!
Factory.registerClass(CLASS_ID, Foo);
public static const CLASS_ID : uint = 42;
}
AFAIK, the JIT machine for the ActionScript language won't let me do that since no reference to Foo is made in the Main method. The Foo class being generated, I can't (and don't want to) register the classes in Main: I'd like to register all the exported classes in a specific package (or library). Ideally, this would be done through package introspection, which doesn't exist in ActionScript 3.
Do you know any fix (or other solution) to my design issue?
I'm not 100% sure sure if this is what you're after, but have you tried using a Static Initializer?
public class Foo
{
// Static Initializer
{
Factory.registerClass(CLASS_ID, Foo);
}
public static const CLASS_ID : uint = 42;
}
http://life.neophi.com/danielr/2006/12/static_initializers_in_as3.html
You can use compiler options to include class byte code in the resulting SWF or SWC. But you have to compile with MXMLC (or COMPC for SWCs).