views:

173

answers:

1

Is it possible to build something that works like an ISubDependencyResolver but also supports Release(...)?

I have a situation where I want to be able to resolve a derived class of Fruit in the constructor of a Blender:

abstract class Fruit
{
}

class AppleBlender
{
    AppleBlender(Apple a)
    {
    }
}

Apple is unfortunately in a different assembly that I don't want to load until required because there are hundreds of different kinds of Fruit all with their own assembly.

ISubDependencyResolver works great for this except that some of my Fruit are disposable, so I need a way for them to be released.

Is deriving from the DefaultDependencyResolver the only way to achieve this?

EDIT: More comprehensive example.

[TestFixture]
public class SubResolverFixture
{
 [Test]
 public void ResolvedInstanceShouldBeDisposed()
 {
  IKernel kernel = new DefaultKernel();
  kernel.Resolver.AddSubResolver(new TestResolver());

  kernel.Register(Component.For<AppleBlender>().LifeStyle.Transient);

  AppleBlender ab = kernel.Resolve<AppleBlender>();
  kernel.ReleaseComponent(ab);

  Assert.That(ab.IsDisposed);
  Assert.That(ab.Apple.IsDisposed);
 }
}

public class TestResolver : ISubDependencyResolver
{
 public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
 {
  return new Apple();
 }

 public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
 {
  return typeof(Fruit).IsAssignableFrom(dependency.TargetType);
 }
}

public abstract class Fruit : IDisposable
{
 public bool IsDisposed
 {
  get;
  set;
 }

 public void Dispose()
 {
  IsDisposed = true;
 }
}

public class Apple : Fruit
{
}

public class AppleBlender : IDisposable
{
 public AppleBlender(Apple apple)
 {
  Apple = apple;
 }

 public Apple Apple
 {
  get;
  set;
 }

 public bool IsDisposed
 {
  get;
  set;
 }

 public void Dispose()
 {
  IsDisposed = true;
 }
}

Basically I want a way to treat the "new Apple()" as a transient object that needs to be disposed. I am completely happy to take an entirely different track on this one, but the type "Apple" needs to be loaded at resolve time (not startup time).

A: 

Windsor 2.5 supports this OOTB for components registered via UsingFactoryMethod (or more broadly speaking for components that have implementation type set to LateBoundComponent)

Krzysztof Koźmic