Dependency injection 为什么';温莎不能解决我注册的每一个装饰师吗?

Dependency injection 为什么';温莎不能解决我注册的每一个装饰师吗?,dependency-injection,castle-windsor,Dependency Injection,Castle Windsor,我有一个班级,我想装饰两次。然而,当我解决这个类时,Windsor只装饰它一次,而不是使用我的2个装饰器。我不确定为什么会这样,因为我在解析类之前注册了两个decorator,这就是我如何理解decorators与Windsor一起工作的原因 这是我的密码 public interface IQueryExecuter { TReturn Execute<TReturn>(IQuery<TReturn> query); } public class QueryL

我有一个班级,我想装饰两次。然而,当我解决这个类时,Windsor只装饰它一次,而不是使用我的2个装饰器。我不确定为什么会这样,因为我在解析类之前注册了两个decorator,这就是我如何理解decorators与Windsor一起工作的原因

这是我的密码

public interface IQueryExecuter
{
    TReturn Execute<TReturn>(IQuery<TReturn> query);
}

public class QueryLoggingDecorator : IQueryExecuter
{
    private ILogger _logger = NullLogger.Instance;

    public ILogger Logger
    {
        set { _logger = value; }
    }

    public TReturn Execute<TReturn>(IQuery<TReturn> query)
    {
        _logger.Info("Before query execute");
        var queryResults = query.Execute();
        _logger.Info("After query execute");

        return queryResults;
    }
}

public class QueryTransactionDecorator : IQueryExecuter
{
    public TReturn Execute<TReturn>(IQuery<TReturn> query)
    {
        try
        {
            Console.WriteLine("Beginning transaction");
            var queryResults = query.Execute();
            Console.WriteLine("Comitting transaction");

            return queryResults;
        }
        catch (Exception)
        {
            Console.WriteLine("Rolling back transaction");
            throw;
        }
    }
}

public interface IQuery<out TReturn>
{
    TReturn Execute();
}

public class Query : IQuery<string>
{
    public string Execute()
    {
        Console.WriteLine("Executing query");

        var queryResults = Path.GetRandomFileName();

        return queryResults;
    }
}
公共接口IQueryExecuter
{
TReturn执行(IQuery查询);
}
公共类QueryLoggingDecorator:IQueryExecuter
{
private ILogger _logger=NullLogger.Instance;
公共ILogger记录器
{
设置{u logger=value;}
}
公共TReturn执行(IQuery查询)
{
_logger.Info(“查询执行前”);
var queryResults=query.Execute();
_logger.Info(“查询执行后”);
返回查询结果;
}
}
公共类QueryTransactionDecorator:IQueryExecuter
{
公共TReturn执行(IQuery查询)
{
尝试
{
Console.WriteLine(“开始交易”);
var queryResults=query.Execute();
控制台。写入线(“提交交易”);
返回查询结果;
}
捕获(例外)
{
Console.WriteLine(“回滚交易”);
投掷;
}
}
}
公共接口iquiry
{
TReturn Execute();
}
公共类查询:IQuery
{
公共字符串Execute()
{
Console.WriteLine(“执行查询”);
var queryResults=Path.GetRandomFileName();
返回查询结果;
}
}
这是我的温莎注册码

public class DefaultInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Component
            .For<IQueryExecuter>()
            .ImplementedBy<QueryLoggingDecorator>()
            .LifestyleTransient());
        container.Register(Component
            .For<IQueryExecuter>()
            .ImplementedBy<QueryTransactionDecorator>()
            .LifestyleTransient());
        container.Register(Component
            .For<IQueryExecuter>()
            .ImplementedBy<QueryExecuter>()
            .LifestyleTransient());
    }
}
public类DefaultInstaller:IWindsorInstaller
{
public void安装(IWindsorContainer、IConfigurationStore)
{
容器寄存器(组件
.对于()
.由()实施
.生活方式(暂时的);
容器寄存器(组件
.对于()
.由()实施
.生活方式(暂时的);
容器寄存器(组件
.对于()
.由()实施
.生活方式(暂时的);
}
}
最后,这是我的呼叫代码

var container = new WindsorContainer();

container.Install(FromAssembly.This());

var queryExecuter = container.Resolve<IQueryExecuter>();
var queryResults = queryExecuter.Execute(new Query());
var容器=新的WindsorContainer();
container.Install(fromsassembly.This());
var queryExecuter=container.Resolve();
var queryResults=queryExecuter.Execute(newquery());
我错过了什么


我希望当我解决
IQueryExecuter
问题时,温莎会用
QueryLoggingDecorator
进行装饰,然后
QueryTransactionDecorator
,问题是他们不是装饰者;它们只是同一接口的不同实现。装饰器需要一些实际装饰的东西,这是他们正在实现的同一接口的实例,因此他们可以调用链中的下一个装饰器

您需要设置对IQueryExecuter的可注入引用。在那之后,温莎处理其余的事情,按照注册顺序注入装饰链(至少,根据文档)

例如:

public class QueryLoggingDecorator : IQueryExecuter
{
    private ILogger _logger = NullLogger.Instance;
    private IQueryExecuter innerExecuter;

    public QueryLoggingDecorator(IQueryExecuter innerExecuter)
    {
        this.innerExecuter = innerExecuter;
    }


    public ILogger Logger
    {
        set { _logger = value; }
    }

    public TReturn Execute<TReturn>(IQuery<TReturn> query)
    {
        _logger.Info("Before query execute");
        var queryResults = innerExecuter.Execute(query);
        _logger.Info("After query execute");

        return queryResults;
    }
}
公共类QueryLoggingDecorator:IQueryExecuter
{
private ILogger _logger=NullLogger.Instance;
私人执行器;内部执行器;
公共QueryLoggingDecorator(IQueryExecuter-innerExecuter)
{
this.innerExecuter=innerExecuter;
}
公共ILogger记录器
{
设置{u logger=value;}
}
公共TReturn执行(IQuery查询)
{
_logger.Info(“查询执行前”);
var queryResults=innerExecuter.Execute(查询);
_logger.Info(“查询执行后”);
返回查询结果;
}
}

我承认我没有直接尝试,但表示它会起作用。

问题是这些人不是装饰师;它们只是同一接口的不同实现。装饰器需要一些实际装饰的东西,这是他们正在实现的同一接口的实例,因此他们可以调用链中的下一个装饰器

您需要设置对IQueryExecuter的可注入引用。在那之后,温莎处理其余的事情,按照注册顺序注入装饰链(至少,根据文档)

例如:

public class QueryLoggingDecorator : IQueryExecuter
{
    private ILogger _logger = NullLogger.Instance;
    private IQueryExecuter innerExecuter;

    public QueryLoggingDecorator(IQueryExecuter innerExecuter)
    {
        this.innerExecuter = innerExecuter;
    }


    public ILogger Logger
    {
        set { _logger = value; }
    }

    public TReturn Execute<TReturn>(IQuery<TReturn> query)
    {
        _logger.Info("Before query execute");
        var queryResults = innerExecuter.Execute(query);
        _logger.Info("After query execute");

        return queryResults;
    }
}
公共类QueryLoggingDecorator:IQueryExecuter
{
private ILogger _logger=NullLogger.Instance;
私人执行器;内部执行器;
公共QueryLoggingDecorator(IQueryExecuter-innerExecuter)
{
this.innerExecuter=innerExecuter;
}
公共ILogger记录器
{
设置{u logger=value;}
}
公共TReturn执行(IQuery查询)
{
_logger.Info(“查询执行前”);
var queryResults=innerExecuter.Execute(查询);
_logger.Info(“查询执行后”);
返回查询结果;
}
}
我承认我没有直接尝试,但表示它会起作用