0

Is it possible to register Interface1 below based on Interface2's custom attribute?

public interface Interface1 : Interface2

This implements Interface 2 which has a ServiceContract attribute

[ServiceContract]
public interface Interface2

and I want to do something like this so that it works out Interface1 inherits something with the ServiceContractAttribute and so registers Interface1.

    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.AddFacility<TypedFactoryFacility>();

        container.Register(
            Classes.FromThisAssembly()
                .Where(type => !type.IsInterface && type.GetInterfaces().Any(t => t.GetCustomAttributes(typeof(ServiceContractAttribute), true).Any()))
                .WithServiceAllInterfaces()
                .LifestylePerWcfOperation(),

However the above code doesn't seem to register inherited interfaces, but it will register Interface2 fine.

The class is as below:

public class AddressService : AnotherService, Interface1
{
    public AddressService() 
        : base(anotherService)
    {
    }
}
2
  • Do you have two classes, one which implements Interface1 and another which implements Interface2? Commented Feb 6, 2015 at 13:38
  • @DoctorMick No just one class that implements Interface1, I was hoping to register all classes that implement Interface1 based on the custom attribute of Interface2. There may be many other interfaces X that inherit from Interface2 in the future and I wanted those classes X to automatically register based on that attribute in Interface2. Commented Feb 6, 2015 at 13:44

1 Answer 1

1

It looks like the default Windsor behaviour when a class implements multiple interfaces it to use the highest level one. If you want to be able to resolve only using Interface1 you can use .WithServiceFirstInterface like so:

container.Register(
    Classes.FromThisAssembly()
        .Where(type => !type.IsInterface && type.GetInterfaces().Any(t => t.GetCustomAttributes(typeof (ServiceContractAttribute), true).Any()))
         .WithServiceFirstInterface()
         .LifestylePerWcfOperation());

If you want to be able to resolve the concrete by any of it's interfaces you can use WithServiceAllInterfaces.

Make sure you're adding the Windsor WCF facility when you setup your container:

container.AddFacility<WcfFacility>

And finally, use the windor factory by changing your svc like so;

<%@ ServiceHost Language="C#" Debug="true" Service="Reference.AddressService" Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" %>
Sign up to request clarification or add additional context in comments.

9 Comments

Neither worked unfortunately, its because the custom attribute us in Interface2 I think, and my class implements Interface1.
Shouldn't matter, the snippet above registered a class which implemented Interface1 and by changing to WithServiceAllInterfaces it registered it against both interfaces. Can you post your class and also the code you're using to try and resolve?
edited above, thanks, the error I get is: ComponentActivator: could not instantiate System.ServiceModel.ChannelFactory`1[[Contracts.Reference.Interface1, Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
I forgot to mention if it helps, I am using WCF contract first, so the error is occuring on my layer above the WCF layer, which looks for an endpoint for Interface1 in its web.config, which doesn't have a ServiceContractAttribute
Is the exception definitely coming from Windsor or is it a standard WCF error? Are you registering the WcfFacility and using the Windsor WCF Integration DefaultServiceHostFactory?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.