简体   繁体   中英

Castle Windsor Inline dependencies

I need to use Inline Dependencies feature of castle-windsor. I need to inject specific component in chain of dependencies. I have a situation like this.

static void Main(string[] args)
{
    var container = new Castle.Windsor.WindsorContainer();

    container.Register(
        Component.For<IHigherBusiness>()
                 .ImplementedBy<HigherBusiness>()
                 .DependsOn(Dependency.OnComponent<ILogger, FullDetailLogger>())
        );

    container.Register(Component.For<ISomeBusiness>()
                 .ImplementedBy<Business>());
    container.Register(Component.For<ILogger>()                         
                 .ImplementedBy<FullDetailLogger>().IsFallback());
    container.Register(Component.For<ILogger>()
                 .ImplementedBy<SimpleLogger>());

    var business = container.Resolve<IHigherBusiness>();
    business.DoSomething();

    var logger = container.Resolve<ILogger>();
    logger.Log("Some Log... ."); 
}

with business ...

public interface IHigherBusiness
{
    void DoSomething();
}

public class HigherBusiness : IHigherBusiness
{
    private ISomeBusiness someBusiness;

    public HigherBusiness(ISomeBusiness someBusiness)
    {
        this.someBusiness = someBusiness;
    }
    public void DoSomething()
    {
        someBusiness.DoSomething();
    }
}

public interface ISomeBusiness
{
    void DoSomething();
}

public class Business : ISomeBusiness
{
    private ILogger logger;
    public Business(ILogger logger)
    {
        this.logger = logger;
    }
    public void DoSomething()
    {
        logger.Log("Message");
    }
}

and loggers ...

public interface ILogger
{
    void Log(string message);
}

public class SimpleLogger : ILogger
{

    public void Log(string message)
    {
        Console.WriteLine("Simple Logger: " + message);
    }
}

public class FullDetailLogger : ILogger
{
    public void Log(string message)
    {
        Console.WriteLine("Full detail Logger: " + message);
    }
}

The result is:

Simple Logger: Message
Simple Logger: Some Log... .

but I expect this:

Full detail Logger: Message
Simple Logger: Some Log... .

How can I achieve this ?

DependsOn works only one level down so You have to make Business depend on specific ILogger .

You can do a trick like this:

    static void Main(string[] args)
    {

        var container = new Castle.Windsor.WindsorContainer();

        container.Register(
                Component.For<IHigherBusiness>()
                .ImplementedBy<HigherBusiness>()
                .DependsOn(Dependency.OnComponent(typeof(ISomeBusiness),
                            "BusinessWithExtendedLogger"))
            );
        container.Register(Component.For<ISomeBusiness>().ImplementedBy<Business>()
                .DependsOn(Dependency.OnComponent<ILogger, FullDetailLogger>())
                .Named("BusinessWithExtendedLogger")
            );
        container.Register(Component.For<ISomeBusiness>().ImplementedBy<Business>()
                .DependsOn(Dependency.OnComponent<ILogger, SimpleLogger>())
                .IsDefault()
            );
        container.Register(Component.For<ILogger>().ImplementedBy<FullDetailLogger>()
                .IsFallback()
            );
        container.Register(Component.For<ILogger>().ImplementedBy<SimpleLogger>());

        var business = container.Resolve<IHigherBusiness>();
        business.DoSomething();

        var normalBusiness = container.Resolve<ISomeBusiness>();
        normalBusiness.DoSomething();

        var logger = container.Resolve<ILogger>();
        logger.Log("Some Log... .");
        Console.ReadKey();

    }

This returns:

Full detail Logger: Message

Simple Logger: Message

Simple Logger: Some Log... .

Giving You FullDetailLogger only for IHigherBussiness

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM