Register by base interface

1 view
Skip to first unread message

Martin Nilsson

unread,
Oct 4, 2008, 9:25:17 AM10/4/08
to castle-pro...@googlegroups.com
I'm registering my services, repositories, etc like this:

http://blog.viabrains.com/2008/10/register-services-in-windsor.html

Couldn't find this feature in microkernel so I implemented it and the patch is attached. Is this something useful?

Now I can write:

//register all services
container.Register(
    AllTypes.FromAssembly(typeof (ProductService).Assembly)
        .BasedOn<IService>()
        .WithService.FromInterface(typeof (IService)));

//register all repositories
container.Register(
    AllTypes.FromAssembly(typeof(ProductRepository).Assembly)
        .BasedOn<IRepository>()
        .WithService.FromInterface(typeof(IRepository)));

This will be the same as

// Register all services
container.Register(
    Component
        .For<IProductService>()
        .ImplementedBy<ProductService>());

container.Register(
    Component
        .For<IOrderService>()
        .ImplementedBy<OrderService>());

// and so on...

If this patch is approved then Castle.MicroKernel-vs2005.csproj needs to be modified as well, I think?

Thoughts? I'm not that happy with the name FromInterface() thou

Cheers,
Martin

public class ProductService : IProductService
{       
}

public interface IProductService : IService
{
}
Register_from_base_interface.patch

Tuna Toksöz

unread,
Oct 4, 2008, 12:49:27 PM10/4/08
to castle-pro...@googlegroups.com
As far as I know, you can register something with its FirstInterface.

Martin Nilsson

unread,
Oct 4, 2008, 2:53:00 PM10/4/08
to castle-pro...@googlegroups.com
Yes, but what is first interface?

http://msdn.microsoft.com/en-us/library/system.type.getinterfaces.aspx

"The GetInterfaces method does not return interfaces in a particular order, such as alphabetical or declaration order. Your code must not depend on the order in which interfaces are returned, because that order varies."

For example. when registering my views I have this:

MyForm : Form, IMyForm

Form implements more than 20 interfaces..

To register all my views I can write:

container.Register(
    AllTypes.FromAssembly(typeof (MyForm).Assembly)
        .BasedOn<IView>()
        .WithService.FromInterface(typeof (IView)));

heyn...@gmail.com

unread,
Oct 4, 2008, 3:02:19 PM10/4/08
to Castle Project Development List
+1 on that! :)

On Oct 4, 7:53 pm, "Martin Nilsson" <mffmar...@gmail.com> wrote:
> Yes, but what is first interface?
>
> http://msdn.microsoft.com/en-us/library/system.type.getinterfaces.aspx
>
> "The GetInterfaces method does not return interfaces in a particular order,
> such as alphabetical or declaration order. Your code must not depend on the
> order in which interfaces are returned, because that order varies."
>
> For example. when registering my views I have this:
>
> MyForm : Form, IMyForm
>
> Form implements more than 20 interfaces..
>
> To register all my views I can write:
>
> container.Register(
>     AllTypes.FromAssembly(typeof (MyForm).Assembly)
>         .BasedOn<IView>()
>         .WithService.FromInterface(typeof (IView)));
>
> On Sat, Oct 4, 2008 at 6:49 PM, Tuna Toksöz <tehl...@gmail.com> wrote:
> > As far as I know, you can register something with its FirstInterface.
>

Tuna Toksöz

unread,
Oct 4, 2008, 3:07:05 PM10/4/08
to castle-pro...@googlegroups.com
Agh looks like you found a possible bug.
--
Tuna Toksöz

Typos included to enhance the readers attention!

Craig Neuwirt

unread,
Oct 4, 2008, 3:35:44 PM10/4/08
to castle-pro...@googlegroups.com
Martin,

  I like your suggestion.  I'll roll it in.

FirstInterface does just what is says, gets the first interface.  No semantics assumed.  Usually used for impls with single interfaces.

thanks,
 craig

Craig Neuwirt

unread,
Oct 4, 2008, 3:57:04 PM10/4/08
to castle-pro...@googlegroups.com
Martin,

  In your test case, why wouldn't you want CommonImpl1 and CommonImpl2 to be registered as service ICommon.  If would seem that if no parent interface is found, and the component implements the base interface that it should use that one

Martin Nilsson

unread,
Oct 4, 2008, 5:16:45 PM10/4/08
to castle-pro...@googlegroups.com
yes, that would be correct. Will fix that tomorrow

Craig Neuwirt

unread,
Oct 4, 2008, 5:19:31 PM10/4/08
to castle-pro...@googlegroups.com
I'll take care of it.  I already pulled in your patch.

If the the BasedOn service is deep in the inheritance chain, it is possible that it will pick an intermediate interface and not the topmost.  Its the same uncertainty that happens with FirstInterface. Right?

Ayende Rahien

unread,
Oct 4, 2008, 5:20:45 PM10/4/08
to castle-pro...@googlegroups.com
Probably we need to also allow automatic mapping for IFoo to Foo and IFoo to FooImpl

Craig Neuwirt

unread,
Oct 4, 2008, 5:28:26 PM10/4/08
to castle-pro...@googlegroups.com
Can you explain?

Martin Nilsson

unread,
Oct 4, 2008, 6:04:38 PM10/4/08
to castle-pro...@googlegroups.com
No, you are not guaranteed to get the topmost but now I can have more than one interface and in no particular order.

ProductService : IFoo, IProductService, IBar

IFoo : IFooBase
IProductService : IProductServiceBase
IProductServiceBase : IService
IBar

Now the order of the interfaces doesn't matter. But as you said, you could get IProductServiceBase as the service because of GetInterface doesn't guarantee anything. Don't have any solution to this currently.

Still I think it is an elegant way to auto register your services, repositories, views, etc.
In my example here I also had typesToIgnore. That might be useful when you want to autoregister all your services but pic a specific implementation for one or more. Like ITaxCalculator service I want to specify myself. Didn't implement that in the patch because I first wanted your opinion about auto registering.

Craig Neuwirt

unread,
Oct 4, 2008, 6:25:01 PM10/4/08
to castle-pro...@googlegroups.com
On Sat, Oct 4, 2008 at 5:04 PM, Martin Nilsson <mffm...@gmail.com> wrote:
No, you are not guaranteed to get the topmost but now I can have more than one interface and in no particular order.

ProductService : IFoo, IProductService, IBar

IFoo : IFooBase
IProductService : IProductServiceBase
IProductServiceBase : IService
IBar

Now the order of the interfaces doesn't matter. But as you said, you could get IProductServiceBase as the service because of GetInterface doesn't guarantee anything. Don't have any solution to this currently.

I don't think we need to worry about that. 

Still I think it is an elegant way to auto register your services, repositories, views, etc.
In my example here I also had typesToIgnore. That might be useful when you want to autoregister all your services but pic a specific implementation for one or more. Like ITaxCalculator service I want to specify myself. Didn't implement that in the patch because I first wanted your opinion about auto registering.

The built in support for auto-registering components seems to cover about 90% of the cases, views, controllers, repositories.,,
For special situations and registering multiple services I use the same type of approach in your example.  I have static methods that I feed to Select.
 

Ken Egozi

unread,
Oct 4, 2008, 6:57:49 PM10/4/08
to castle-pro...@googlegroups.com
+1 for Ayende's suggestion

AllDefaultFrom(assembly)
will register all types that adhere to
IService -> Service
or
IService -> DefaultService
or
IService -> ServiceImpl

Martin Nilsson

unread,
Oct 5, 2008, 2:22:01 AM10/5/08
to castle-pro...@googlegroups.com
Ken,
Not really follow you here.. Do you mean that you have three cases here that looks like this:

IService -> Service (Service:IService)
or
IService -> DefaultService (DefaultService:Service)
or
IService -> ServiceImpl (ServiceImpl:DefaultService)

How is that different then from my impl?

But I like AllDefault but I think it have to look something like this:

container.Register(AllDefault<IService>(typeof (ProductService).Assembly));

That would replace

container.Register(
    AllTypes.FromAssembly(typeof (ProductService).Assembly)
        .BasedOn<IService>()
        .WithService.FromInterface(typeof (IService)));

Sweet!
Reply all
Reply to author
Forward
0 new messages