Re: Nested named lifetimescopes

31 views
Skip to first unread message

Alex Meyer-Gleaves

unread,
Apr 28, 2013, 9:10:38 AM4/28/13
to aut...@googlegroups.com
Hi Andrew,

I have to admit that I'm not really able to follow your example. It seems that a house only has one room, so to create a new room requires a new instance of house. 

Perhaps that is why in your RegisterOwner method you are creating a new lifetime scope that is not being disposed. You are also not using the parentKey parameter so the lifetime scopes are not nested.

Are you following the MVVM pattern in your WPF application? Can you build a simple model and move your service logic into separate classes that the view model can use?

If you can provide some more information about your scenario and the model we might be able to help you work something out.

Cheers,

Alex.


On Saturday, 27 April 2013 03:16:22 UTC+10, Andrew Clancy wrote:
Hi

We've got a small scenario that's probably best described through code (which follows) - essentially we've got nested lifetimescopes, both named, and want to share a singleton between them, but we're not able to resolve it in the child lifetimescope.  (I'm sure there'll be a question as to 'why': its essentially around a nested workspace/document model inside a wpf UI). The following sample scenario has houses in named lifetimescopes, an electricity supply per house, rooms in their own named lifetimescopes, then applicances in rooms. We try to resolve an appliance, which needs the electricity supply, and get the following exception. Any ideas?

Autofac.Core.DependencyResolutionException : No scope with a Tag matching 'HouseScope' is visible from the scope in which the instance was requested.

private IContainer _container;
private ContainerBuilder _containerBuilder;

[Test]
public void ChildScopeShouldResolveSingletonFromAncestorScope()
{
    // ARRANGE
    _containerBuilder = new ContainerBuilder();
    RegisterOwner<IHouse, House>("HouseScope");
    RegisterSingletonPerOwner<IElectricitySupply, ElectricitySupply>("HouseScope");

    RegisterOwner<IRoom, Room>("RoomScope", "HouseScope");
    RegisterSingletonPerOwner<IApplianceController, ApplianceController>("RoomScope");

    _containerBuilder.RegisterType<Room>();
    _containerBuilder.RegisterType<House>();
    _containerBuilder.RegisterType<Appliance>();

    _container = _containerBuilder.Build();

    // ACT
    var housesWorkspace = _container.Resolve<IHouse>();
    var house = _container.Resolve<IRoom>();
    var appliance = house.CreateAppliance();

    // ASSERT
    Assert.IsNotNull(housesWorkspace);
    Assert.IsNotNull(house);
}

public void RegisterOwner<TInterface, TConcrete>(string key, string parentKey = null)
    where TConcrete : TInterface
{
    _containerBuilder.Register<TInterface>(
        c =>
            {
                var lifetimeScope = _container.BeginLifetimeScope(key);
                var concrete = lifetimeScope.Resolve<TConcrete>();
                return concrete;
            });
}

public void RegisterSingletonPerOwner<TInterface, TConcrete>(string key) where TConcrete : TInterface
{
    _containerBuilder.RegisterType<TConcrete>()
        .As<TInterface>()
        .InstancePerMatchingLifetimeScope(key);
}

public interface IHouse : IDisposableObject
{
    IRoom Room { get; set; }
}

public class House : DisposableObject, IHouse
{
    public House(IRoom house)
    {
        Room = house;
    }

    public IRoom Room { get; set; }
}

public interface IRoom : IDisposableObject
{
    Appliance CreateAppliance();
}

public class Room : DisposableObject, IRoom
{
    private readonly Func<Appliance> _applianceFactory;

    public Room(Func<Appliance> applianceFactory, IApplianceController applianceController)
    {
        _applianceFactory = applianceFactory;
    }

    public Appliance CreateAppliance()
    {
        return _applianceFactory();
    }
}

public interface IApplianceController : IDisposableObject { }

public class ApplianceController : DisposableObject, IApplianceController { }

public class Appliance : DisposableObject
{
    public Appliance(IApplianceController applianceController, IElectricitySupply workspaceService) { }
}

public interface IElectricitySupply : IDisposableObject { }
public class ElectricitySupply : DisposableObject, IElectricitySupply { }

Reply all
Reply to author
Forward
0 new messages