Assume we have IFoo implemented by Foo and IBar implemented by FirstBar and SecondBar.
Using this convention registration:
container.Register(
AllTypes.FromThisAssembly().Pick()
.WithService.DefaultInterface())
We'll have three entries in the container:
IFoo = Foo
IBar = FirstBar
IBar = SecondBar
Now, how can we tweak this registration to be able to tell the container that for IBar we want SecondBar registered only? Sort of:
container.Register(
AllTypes.FromThisAssembly().Pick()
.WithService.DefaultInterface()
.For<IBar>().Select<SecondBar>())
Use case: we have lots of services in our app all registered by conventions. However, some of the service interfaces have two or more implementations (e.g. real implementation, fake implementation and test implementation). Convention registration will register them all under the same interface and while resolving the interface we'll get the first implementation (in nondeterministic order). We want to be able to select one specific implementation for those services while registering. How can we do that?
Tighten your convention. It is obviously to wide.
container.Register(
AllTypes.FromThisAssembly()
.Where(t => t.Namespace != "Acme.Tests")
.WithService.DefaultInterface())
This is what made the work done:
container.Register(
AllTypes.FromThisAssembly().Pick()
.WithService.DefaultInterface())
.ConfigureFor<IBar>(c =>
c.If((k, m) => m.Implementation == typeof(SecondBar)));
This effectively registers only SecondBar impl for IBar service. This way, if there is more than one implementation for given service, we can tell the conventional scanner which impl we want.
We went ahead and created nice little extension methods for this purpose:
public static BasedOnDescriptor Select<TService, TImpl>(this BasedOnDescriptor desc)
{
return desc.ConfigureFor<TService>(c => c.If((k, m) => m.Implementation == typeof(TImpl)));
}
public static BasedOnDescriptor Ignore<TService>(this BasedOnDescriptor desc)
{
return desc.ConfigureFor<TService>(c => c.If((k, m) => false));
}
We can now use it like this:
container.Register(
AllTypes.FromThisAssembly().Pick()
.WithService.DefaultInterface())
.Select<IBar, SecondBar>()
.Ignore<ISomeService>()
All in all this works nicely. I believe those two methods could be in the Castle.Windsor proper. #Krzysztof Koźmic: where do I submit a patch? :)
Related
Dears,
I have an interface IJob that has a method called ExecuteAsync and i want to intercept this method only but my derived classes may have many methods and i found the interceptor intercept them also.
My question is,
Is this possible with Castle Windsor
and this is my registration
iocManager.IocContainer.Kernel.ComponentRegistered += (key, handler) =>
{
var implementationType = handler.ComponentModel.Implementation.GetTypeInfo();
if(ShouldIntercept(implementationType))
{
handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(AuthenticateJobInterceptor)));
}
};
private static bool ShouldIntercept(Type type)
{
if (typeof(IJob).IsAssignableFrom(type))
{
return true;
}
return false;
}
Yes it is. There's a IProxyGenerationHook interface that you can implement to control what gets intercepted. The tutorial I wrote a decade ago still (for better or worse) seems to be the best resource about it.
There's a couple ways to set it up in Windsor.
Ideally, if possible, you'd do it during registration, in your IWindsorInstaller:
var yourHook = new YourHook();
container.Register(
Classes.FromThisAssembly()
.BasedOn<IJob>()
.LifestyleTransient()
.WithServiceBase()
.Configure(c =>
c.Interceptors<AuthenticateJobInterceptor>()
.Proxy.Hook(yourHook)));
Alternatively, if you want to keep your code similar to what it is now (I'd recommend wrapping in a ComponentModel construction contributor), you can do something like:
var options = handler.ComponentModel.ObtainProxyOptions();
options.Hook = yourHook; // InstanceReference(yourHook)
My application uses the "SignalR" client/server comms framework. If you aren't familiar with it, the server-side app typically contains one or more "hub" classes (similar to asmx web services), each providing methods that can be called by a client. During startup, the client needs to first create a connection, then create a "proxy" for each hub that it will need to talk to, e.g.:-
var hubConnection = new HubConnection("http://...");
var fooHubProxy = hubConnection.CreateHubProxy("FooHub");
var barHubProxy = hubConnection.CreateHubProxy("BarHub");
...etc...
The string parameter passed to CreateHubProxy() is the name of the server-side hub class. The method return type is IHubProxy.
It feels like I should be able to utilise Windsor here, but I'm struggling to find a solution. My first thought was to instantiate the hub proxies and register these instances with Windsor (by name), e.g.
var fooHubProxy = hubConnection.CreateHubProxy("FooHub");
container.Register(Component.For<IHubProxy>().Instance(fooHubProxy).LifestyleSingleton().Named("FooHub"));
...etc...
The problem is that when a class needs a hub proxy, the only way to resolve it by name is to use service locator pattern, which isn't recommended. What other Windsor features (e.g. typed factories, etc.) might be useful here?
Edit
I've just found Windsor's .UsingFactoryMethod, and am wondering if this would work, to simplify hub registration:
container.Register(Component.For<IHubProxy>()
.UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("FooHub"))
.LifestyleSingleton()
.Named("FooHub"));
I guess I still have the problem of how to resolve by name though.
Two years later, but I have a more elegant solution for other people that stummble accross this problem too.
It is possible to use TypedFactory facility and adapt it to you needs like here.
first create the factory interface (only! no need for the actual implementation, castle will take care of that):
public interface IHubProxyFactory
{
IHubProxy GetProxy(string proxyName);
}
Now we need a class that extend the default typed facotory and retreives the component's name from the input (proxyName):
class NamedTypeFactory : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
string componentName = null;
if (arguments!= null && arguments.Length > 0)
{
componentName = arguments[0] as string;
}
if (string.IsNullOrEmpty(componentName))
componentName = base.GetComponentName(method, arguments);
return componentName;
}
}
And then register the factory with castle and specify that your NamedTypeFactory will be used:
Component.For<IHubProxyFactory>().AsFactory(new NamedTypeFactory())
Now every class can get the factory interface in its constructor:
public class SomeClass
{
private IHubProxy _fooHub;
private IHubProxy _barHub;
public SomeClass(IHubProxyFactory hubProxyFactory)
{
_fooHub = hubProxyFactory.GetProxy("FooHub");
_barHub = hubProxyFactory.GetProxy("BarHub");
}
}
Okay, I think I've found a possible solution, partly using the approach detailed here which shows how it is possible to register Func<>s with Windsor.
First, I register a delegate (Func<>) that uses the container to resolve by name:-
Container.Register(Component.For<Func<string, IHubProxy>>()
.Instance(name => Container.Resolve<IHubProxy>(name))
.LifestyleSingleton());
Think of this as an IHubProxy "factory".
Next, I register my hub proxies as detailed in my original question:-
container.Register(Component.For<IHubProxy>()
.UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("FooHub"))
.LifestyleSingleton()
.Named("FooHub"));
container.Register(Component.For<IHubProxy>()
.UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("BarHub"))
.LifestyleSingleton()
.Named("BarHub"));
Here is an example of a class that needs instances of the hub proxies:-
public class SomeClass
{
private IHubProxy _fooHub;
private IHubProxy _barHub;
public SomeClass(Func<string, IHubProxy> hubProxyFactory)
{
_fooHub = hubProxyFactory("FooHub");
_barHub = hubProxyFactory("BarHub");
}
}
Untried so far, but it looks promising. It's a clever solution but injecting the Func<> feels a little hacky, so I would still be keen to hear of other possible solutions to my problem.
I just used a similar method to yours. I use a typed Factory. Advantage is I have type safety for my hubs. Registering the hubs is the same. The rest differs a bit but is technical the same.
IServiceFactory {
IHubProxy GetFooHub();
IHubProxy GetBarHub();
}
And Registration:
Container.AddFacility<TypedFactoryFacility>();
Container.Register(Component.For<IServiceFactory>().AsFactory());
Usage:
public class SomeClass
{
private IHubProxy _fooHub;
private IHubProxy _barHub;
public SomeClass(IServiceFactry hubProxyFactory)
{
_fooHub = hubProxyFactory.GetFooHub();
_barHub = hubProxyFactory.GetBarHub();
}
}
Btw. Factory.Get"Name"() resolves by name.
Disclaimer
Please don't just vote to close this because the title looks subjective, and if it's been asked before please point me to the previous question in the comments and I'll delete this one -- I really did look high and low trying to find a previous question on the subject.
Background
Given I have the following interface and concrete implementation:
public interface IFoo
{
// Some stuff
}
public class Foo : IFoo
{
// Concrete implementations of stuff
}
And somewhere I have the following method:
public Foo GiveMeAFoo()
{
return new Foo();
}
I have traditionally always returned Foo, seeing as it is inherently an IFoo anyway, so it can be consumed at the other end as an IFoo:
IFoo foo = GiveMeAFoo();
The main advantage of this that I can see is that if I really need to consume Foo somewhere as the concrete implementation, I can.
Actual Question
I recently came across some comments on another question, giving someone a hard time for doing this, suggesting the return type should be IFoo.
Am I wrong or are they? Can anyone give me a reason why returning the concrete implementation is a bad idea?
I know that it makes sense to require an IFoo when receiving a parameter to a method, because the less specific a parameter is, the more useful a method is, but surely making the return type specific is unreasonably restrictive.
Edit
The use of IFoo and Foo might have been too vague. Here's a specific example from .NET (in .NET, arrays implement IEnumerable -- i.e. string[] : IEnumerable<string>)
public string[] GetMeSomeStrings()
{
return new string[] { "first", "second", "third" };
}
Surely it's a bad idea to return IEnumerable here? To get the length property you'd now have to call Enumerable.Count(). I'm not sure about how much is optimised in the background here, but logic would suggest that it's now going to have to count the items by enumerating them, which has got to be bad for performance. If I just return the array as an array, then it's a straight property lookup.
If you want your method to be the most flexible that it can be, you should return the least derived type (in your case, IFoo):
public interface IFoo { }
public class Foo : IFoo { }
public IFoo GiveMeAFoo() { return new Foo(); }
That will allow you to change the concrete implementation of IFoo internal to your method without breaking anybody that is consuming your method:
public interface IFoo { }
public class Foo : IFoo { }
public class Foo2 : IFoo { }
public IFoo GiveMeAFoo() { return new Foo2(); }
You can create a bunch of interfaces and give it to different teams. Taking your own example
public interface IFoo
{
// Some stuff
}
public interface IBar
{
public IFoo getMeAFoo();
}
Then you can give these interfaces to a person developing a front end app and he doesn't have to know what the concrete implementation is. The guy developing the front end can use the getMeAFoo() method knowing that it returns an object of IFoo whereas the concrete implementation can be developed separately as:
public class Foo implements IFoo
{
// more stuff
}
public class MoreFoo implements IFoo
{
//
}
public class WunderBar implements IBar
{
public IFoo getMeAFoo()
{
case 1:
return new Foo();
case 2:
return new MoreFoo();
}
}
Hope this makes sense :)
In my opinion, it's always better to return the most abstract type you can. If you find yourself in need for anything that's specific to the type you ar actually returning, I would consider it a code smell.
The main advantage of this is that you can change your mind about which type you really want to return. The called method is made more decoupled from its callers.
Also, you can possibly remove dependencies. The caller code don't need to know anything about the actual type you chose to create.
My final remark is a quotation from Eric Lippert: "You probably should not return an array as the value of a public method or property". (His article is focused in C#, but the general idea is language-agnostic)
Fine, everywhere you use it, you use IFoo foo = GiveMeAFoo();
Then someone else uses your code and doesn't use it that way, for whatever reason, they use Foo foo = GiveMeAFoo();
Now they see all the functionality of Foo that isn't (for good reason) part of IFoo. Now they can use parts of the implementation that aren't part of the interface. Now you can't change your implementation without breaking their code, your implementation is now the public API and you are going to tick people off if you try to change your implementation details that they are counting on.
Not good.
imagine there are two interfaces arranged via composite pattern, one of them has a dispose method among other methods:
interface IComponent extends ILeaf {
...
function dispose() : void;
}
interface ILeaf {
...
}
some implementations have some more things in common (say an id) so there are two more interfaces:
interface ICommonLeaf extends ILeaf {
function get id() : String;
}
interface ICommonComponent extends ICommonLeaf, IComponent {
}
so far so good. but there is another interface which also has a dispose method:
interface ISomething {
...
function dispose() : void;
}
and ISomething is inherited by ICommonLeaf:
interface ICommonLeaf extends ILeaf, ISomething {
function get id() : String;
}
As soon as the dispose method is invoked on an instance which implements the ICommonComponent interface, the compiler fails with an ambiguous reference error because ISomething has a method called dispose and ILeaf also has a dispose method, both living in different interfaces (IComponent, ISomething) within the inheritace tree of ICommonComponent.
I wonder how to deal with the situation if
the IComponent, the ILeaf and the ISomething can't change.
the composite structure must also work for for the ICommonLeaf & ICommonComponent
implementations and the ICommonLeaf & ICommonComponent must conform to the ISomething type.
this might be an actionscript-3 specific issue. i haven't tested how other languages (for instance java) handle stuff like this.
You are searching for a solution to the Diamond Problem. C# has an approach to this but basically I would factor the method "dispose" out of your interfaces and create a new "IDisposable".
If the same name like "id" is used twice, it looks like a problem in your code with an ambiguous name. We started to add prefixes to properties and methods. Imagine you have a property "name" that belongs to two different things. Like the "displayName" and the "uniqueName".
This also helps with auto completion. If a DisplayObject is an ILayoutObject and yout type displayObject.layout you get everything layout releated.
It seems casting solves the ambiguity even though it's far from neat.
class SomeComponent implements ICommonComponent {}
var c : ICommonComponent = new SomeComponent();
trace(ISomething(c).dispose()); //compiles
trace(IComponent(c).dispose()); //compiles
trace(c.dispose()); //fails
As far as I'm aware, there's no neat way to deal with this problem in Actionscript.
The only thing I can think of is refactoring your interfaces to avoid name clashes, which, admitedly, it's not always possible.
Don't know about Java, but C# has a way to handle this through explicit interface implementation.
I'm new to Castle Windsor, so go easy!!
I am developing an MVC web app and one of my controllers has a dependency on knowing the current request Url.
So in my Application_Start I initialise a WindsorContainer (container below), register my controllers and then try the following...
container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<Uri>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => HttpContext.Current.Request.Url));
However when I run up my web app I get an exception that my controller...
is waiting for the following dependencies:
Keys (components with specific keys)
- uri which was not registered.
The controller it is trying to instantiate has the following signature:
public MyController(Uri uri)
For some reason it is not running my factory method?
However if I change the controller signature to:
public MyController(HttpContext httpContext)
and change the registration to:
container.Register(Component.For<HttpContext>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => HttpContext.Current));
Then everything works a treat!!
What am I missing when trying to register a Uri type? Its seems exactly the same concept to me? I must be missing something!?
Updated:
I have done some more debugging and have registered both the Uri and the HttpContext using the factory methods shown above. I have added both types as parameters on my Controller constructor.
So to clarify I have a both Uri and HttpContext types registered and both using the FactoryMethods to return the relevant types from the current HttpContext at runtime. I also have registered my controller that has a dependency on these types.
I have then added a breakpoint after I have registration and have taken a look at the GraphNodes on the kernal as it looks like it stores all the dependencies. Here it is:
[0]: {EveryPage.Web.Controllers.BaseController} / {EveryPage.Web.Controllers.BaseController}
[1]: {EveryPage.Web.Controllers.WebpagesController} / {EveryPage.Web.Controllers.WebpagesController}
[2]: {System.Web.HttpContext} / {System.Web.HttpContext}
[3]: {Castle.MicroKernel.Registration.GenericFactory1[System.Web.HttpContext]} / {Castle.MicroKernel.Registration.GenericFactory1[System.Web.HttpContext]}
[4]: {System.Uri} / {System.Uri}
[5]: {Castle.MicroKernel.Registration.GenericFactory1[System.Uri]} / {Castle.MicroKernel.Registration.GenericFactory1[System.Uri]}
It looks as though it has registered my Controller and both the types, plus it has the Factories. Cool.
Now if I drill into the WebpagesController and take a look at its dependencies it only has 1 registered:
[0]: {System.Web.HttpContext} / {System.Web.HttpContext}
Now shouldn't this have 2 registered dependencies as it takes a HttpContext and Uri on its constructor??
Any ideas? Am I barking up the wrong tree?
UPDATE3:
There's new extension point in Windsor trunk now that you can use easily for that.
UPDATE2:
Turns out that I was right from the start (well kind of). Uri is a class, but Windsor treats it as a primitive. There are still at least two quick solutions to this:
Wrap the Uri in some kind of IHasUri or something and take dependency on that interface in your controller
public class FooController
{
public IHasUri CurrentUri { get; set; }
public void SomeAction()
{
var currentUri = CurrentUri.GetCurrentUri();
// do something with the uri
}
}
Tell the Windsor you don't want it to treat Uris like some primitive (but like a lady).
You need a IContributeComponentModelConstruction implementation for that:
public class UriIsAServiceNotAParameter:IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
if (model.Service != typeof(UsesUri)) // your controller type here
return;
foreach (var constructor in model.Constructors)
{
foreach (var dependency in constructor.Dependencies)
{
if(dependency.TargetType ==typeof(Uri))
{
dependency.DependencyType = DependencyType.Service;
}
}
}
}
}
and add it to the container:
container.Kernel.ComponentModelBuilder.AddContributor(new UriIsAServiceNotAParameter());
There's also the most correct way of doing this, which means telling Windsor not to register Uris as primitives in the first place, rather than fixing this afterwards, but this would require reaching into the deepest guts of the kernel, and the result is far more code (though a straightforwad one) than the workarounds outlined above.