.net - 如何指示 Ninject 从其隐式绑定(bind)列表中隐藏类型

标签 .net dependency-injection ninject ioc-container ninject.web.mvc

Ninject 是否具有我可以用来装饰类或构造函数以让 Ninject 忽略它的属性?

我需要摆脱:

A cyclical dependency was detected between the constructors of two services.



这是我的代码:
// Abstraction
public interface ICommandHandler<TCommand>
{
    void Handle(TCommand command);
}

// Implementation
public class ShipOrderCommandHandler 
    : ICommandHandler<ShipOrderCommand>
{
    private readonly IRepository<Order> repository;

    public ShipOrderCommandHandler(
        IRepository<Order> repository)
    {
        this.repository = repository;
    }

    public void Handle(ShipOrderCommand command)
    {
        // do some useful stuf with the command and repository.
    }
}

我的通用装饰器:
public TransactionalCommandHandlerDecorator<TCommand>
    : ICommandHandler<TCommand>
{
    private ICommandHandler<TCommand> decoratedHandler;

    public TransactionalCommandHandlerDecorator(
        ICommandHandler<TCommand> decoratedHandler)
    {
        this.decoratedHandler = decoratedHandler;
    }

    public void Handle(TCommand command)
    {
        using (var scope = new TransactionScope())
        {
            this.decoratedHandler.Handle(command);
            scope.Complete();
        }
    }
}

我的容器注册:
kernel.Bind(typeof(ICommandHandler<>))
    .To(typeof(TransactionCommandHandlerDecora‌​tor<>));

最佳答案

这是一个基于您的代码的工作示例。

public class AutoDecorationFacts
{
    readonly StandardKernel _kernel = new StandardKernel();

    public AutoDecorationFacts()
    {
        _kernel.Bind( typeof( ICommandHandler<> ) )
            .To( typeof( TransactionalCommandHandlerDecorator<> ) )
            .Named( "decorated" );
    }

    [Fact]
    public void RawBind()
    {
        _kernel.Bind( typeof( ICommandHandler<> ) ).To<ShipOrderCommandHandler>().WhenAnyAnchestorNamed( "decorated" );
        VerifyBoundRight();
    }

    void VerifyBoundRight()
    {
        var cmd = _kernel.Get<ICommandHandler<ShipOrderCommand>>();
        Assert.IsType<TransactionalCommandHandlerDecorator<ShipOrderCommand>>( cmd );
    }

最好与 Ninject.Extensions.Conventions 一起使用:-
    [Fact]
    public void NameSpaceBasedConvention()
    {
        _kernel.Bind( scan => scan
            .FromThisAssembly()
            .SelectAllClasses()
            .InNamespaceOf<CommandHandlers.ShipOrderCommandHandler>()
            .BindAllInterfaces()
            .Configure( x => x.WhenAnyAnchestorNamed( "decorated" ) ) );
        VerifyBoundRight();
    }

    [Fact]
    public void UnconstrainedWorksTooButDontDoThat()
    {
        _kernel.Bind( scan => scan
            .FromThisAssembly()
            .SelectAllClasses()
            .BindAllInterfaces(  )
            .Configure( x=>x.WhenAnyAnchestorNamed("decorated" )));
        VerifyBoundRight();
    }
}

你的课:

公共(public)类 ShipOrderCommand
{
}
// Abstraction
public interface ICommandHandler<TCommand>
{
    void Handle( TCommand command );
}

// Implementation
namespace CommandHandlers
{
    public class ShipOrderCommandHandler
        : ICommandHandler<ShipOrderCommand>
    {
        public ShipOrderCommandHandler(
            )
        {
        }

        public void Handle( ShipOrderCommand command )
        {
            // do some useful stuf with the command and repository.
        }
    }
}
public class TransactionalCommandHandlerDecorator<TCommand>
    : ICommandHandler<TCommand>
{
    private ICommandHandler<TCommand> decoratedHandler;

    public TransactionalCommandHandlerDecorator(
        ICommandHandler<TCommand> decoratedHandler )
    {
        this.decoratedHandler = decoratedHandler;
    }

    public void Handle( TCommand command )
    {
        this.decoratedHandler.Handle( command );
    }
}

(使用 Ninject 和 Ninject.Extensions.Conventions 的 NuGet 最新版本)

关于.net - 如何指示 Ninject 从其隐式绑定(bind)列表中隐藏类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10013262/

相关文章:

c# - 为什么 Tuple<T1...TRest> 中的 TRest 不受约束?

asp.net-mvc - 扩展 ActionDescriptor FilterProvider 以允许类级别过滤器的依赖注入(inject)

c# - DbContext/Ninject Dependency GetService Slow SingleOrDefault 在负载测试下

c# - 如何设置 Winform 文本框字段焦点以便用户可以通过单击 Tab 按钮浏览它们?

c# - ElasticSearch 版本 2.x 中的扫描和滚动替代 (NEST C#)

c# - 如何在 C#.NET/Mono 中使用 HTTP 库来使用请求-响应

jsf - 如何注入(inject)不同的子类作为 ManagedProperty JSF 2?

c# - 如何使用 MvvM 应用依赖注入(inject)?

asp.net-mvc - Ninject/MVC4 - Controller 的集成测试

asp.net-mvc - 从 MVC 中的 _Layout.cshtml 中的 Ninject 获取对象实例