1

I'm using the method described by Bojan Resnik in this question to resolve instances of classes that are not registered in the Windsor container. The problem is that I don't want these classes to be available as "services" to other resolved instances.

For example, given the following classes:

class Order
{
    public Order(ITaxCalculator tc)
    {
        // ...
    }
}

class SomeOtherThing
{
    public SomeOtherThing(ISomeOtherService sos)
    {
        // ...
    }

    Order CurrentOrder
    {
        get;
        set;
    }
}

static class WindsorExtensions
{
    public static object Create(this IWindsorContainer container, Type type)
    {
        if (!type.IsClass)
        {
            throw new ArgumentException("not class", "type");
        }

        if (!container.Kernel.HasComponent(type))
        {
            container.Kernel.AddComponent(type.FullName, type, LifestyleType.Transient);
        }

        return container.Resolve(type);
    }

    public static T Create<T>(this IWindsorContainer container)
    {
        return (T)ResolveType(container, typeof(T));
    }
}

I want to be able to say:

Order order = container.Create<Order>();
SomeOtherThing thing = container.Create<SomeOtherThing>();

But I don't want a new instance of Order to get injected in to the CurrentOrder property of SomeOtherThing. Basically, I want the container to create the instance so that the dependencies can be injected, but I don't want the classes to be available for injection in to other classes.

I don't mind having to write additional extensions to the container in order to achieve this if someone can point me in the right direction.

Community
  • 1
  • 1
Jacob Stanley
  • 4,704
  • 3
  • 33
  • 36

2 Answers2

1

I think this workaround will address your issue since it uses a child kernel for the "unregistered" component, so it shouldn't affect other components.

Mauricio Scheffer
  • 98,863
  • 23
  • 192
  • 275
0

By default windsor uses constructor injection over property injection. Because of this CurrentOrder will never be injected into the SomeOtherThing class unless you add it to the constructor.

Looking at your code you are essentially late registering the component into the container. If you wanted to be sure it was never injected you could remove it once it has resolved eg.

static class WindsorExtensions
{
public static object Create(this IWindsorContainer container, Type type)
{
    if (!type.IsClass)
    {
        throw new ArgumentException("not class", "type");
    }
    if (!container.Kernel.HasComponent(type))
    {
        container.Kernel.AddComponent(type.FullName, type, LifestyleType.Transient);
    }
    object instance = container.Resolve(type);
    container.Kernel.RemoveComponent(type.FullName);
    return instance;

}

public static T Create<T>(this IWindsorContainer container)
{
    return (T)ResolveType(container, typeof(T));
}
}
pythonandchips
  • 2,175
  • 2
  • 25
  • 28