0

I've got a bunch of classes written like this:

public class MyService1 {
    public MyService1(MyService1Settings settings, <service-dependent list of dependencies filled by Windsor>) { ... }
}

which are registered in the Windsor like this:

container.Register(
    ...
    Component.For<MyService1>().LifestyleTransient(),
    Component.For<MyService2>().LifestyleTransient(),
    ...
);

container doesn't have any of the MyServiceXSettings types registered, so the only way to get a service is to resolve it from container like this:

TService service = windsorContainer.Resolve<TService>(new { settings });

The thing is, depending on the parameters in the settings object, one of the services tries to acquire another instance of its type with different settings object.

Something along the lines of:

public class MyService2 {
    public MyService2(MyService2Settings settings, <service-dependent list of dependencies filled by Windsor>)
    {
        this.uplink = settings.Counter == 1
            ? new AnotherUplink()
            : new RecursiveUplink(
                container.Resolve<MyService2>(new {
                    settings = new MyService2Settings(settings.Counter - 1)
                });
    }
}

This recursive dependency chain is finite (and is about 6 instances deep), but Windsor throws an exception when the first service tries to get another one, stating that it's a circular dependency.

I've advertised all the services as having Transient lifestyles and requesting them with custom parameters. Can I at least specify the maximum allowed depth of the recursion? Or am I missing another way I can do it?

another requirement: I can't use typed factories, because I've got quite many different types of those services, so generating many factory interfaces individually for those services would be undesired.

4

2 に答える 2

0

この答えに従って、私は怠惰な解決策を取りました。

/// <summary>
/// Represents single component instance producer.
/// </summary>
/// <typeparam name="TComponent">type of the component to create</typeparam>
public interface IComponentCreator<TComponent>
{
    /// <summary>
    /// Gets the created component.
    /// </summary>
    TComponent Component { get; }
}

/// <summary>
/// Creates the component only when it's first requested.
/// </summary>
/// <typeparam name="TComponent">type of the component to create</typeparam>
public class LazyCreator<TComponent> : IComponentCreator<TComponent>
{
    private readonly Func<TComponent> creatingFunction;
    private bool created;
    private TComponent component;

    public LazyCreator(Func<TComponent> creatingFunction)
    {
        this.creatingFunction = creatingFunction;
    }

    public TComponent Component
    {
        get
        {
            if (!created)
            {
                component = creatingFunction();
                created = true;
            }

            return component;
        }
    }
}

/// <summary>
/// Returns already created component.
/// </summary>
/// <typeparam name="TComponent">type of the component</typeparam>
public class ComponentContainer<TComponent> : IComponentCreator<TComponent>
{
    private readonly TComponent component;

    public ComponentContainer(TComponent component)
    {
        this.component = component;
    }

    public TComponent Component
    {
        get { return component; }
    }
}
于 2013-10-07T20:42:46.853 に答える