views:

33

answers:

1

I looked at this and it answers half my questions:

http://stackoverflow.com/questions/2370546/castle-windsor-register-class-with-internal-constructor

But can you use Windsor to use internal constructors/class along with dependency injection? (so constructor parameters get injected too)? I'd like to keep the class/constructor internal to allow for optimal encapsulation (these classes should not be exposed to the public).

I need this to support Silverlight, so I don't think this is an option:

http://stackoverflow.com/questions/1837020/castle-windsor-how-to-register-internal-implementations

Thanks.

+1  A: 

This may not be a satisfying answer, but it is a best practice to make all classes that you need to instantiate via Castle public, with public constructors. Your design should allow a downstream dependency to instantiate your objects without relying on Castle or InternalsVisibleTo.

To your question, Castle will only search for public constructors to instantiate an object. I don't believe there is a way to make it search for internal or private constructors. However, if your class is internal, you can make your internal constructors public without changing the encapsulation at all. See the following test case:

[TestFixture]
public class InternalConstructorTests
{
    [Test]
    public void Test()
    {
        using (var container = new WindsorContainer())
        {
            container.Register(
                Component.For<IFoo>().ImplementedBy<Foo>(),
                Component.For<IBar>().ImplementedBy<Bar>(),
                Component.For<IBaz>().ImplementedBy<Baz>()
                );
            // fails because Castle can't find, and won't call, the internal constructor
            Assert.Throws<ComponentActivatorException>(()=>container.Resolve<IFoo>());
            // passes because the Baz constructor is public, but the "real" encapsulation
            // level is the same because the class is internal, effectively making the 
            // public constructor internal as well
            container.Resolve<IBaz>();
        }
    }
}
internal interface IBar{}
internal class Bar : IBar{}
internal interface IFoo{}
internal class Foo : IFoo
{
    internal Foo(IBar bar)
    {
    }
}
internal interface IBaz { }
internal class Baz : IBaz
{
    public Baz(IBar bar)
    {
    }
}
Stuart Lange