Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用依赖项注入(Ninject)创建对象管道_C#_Dependency Injection_Ninject - Fatal编程技术网

C# 使用依赖项注入(Ninject)创建对象管道

C# 使用依赖项注入(Ninject)创建对象管道,c#,dependency-injection,ninject,C#,Dependency Injection,Ninject,我在决定如何最好地使用依赖项注入(DI)构建双向对象管道时遇到了一些困难 我目前正在将Ninject作为DI容器进行试验 它实际上比这更复杂,因为我正在考虑用适配器将两个管道绑定在一起 这两条管道由以下接口对(ITransport,ITransportSink)和(IMessageProcessor,IMessageProcessorSink)定义: public interface ITransport { void Connect(); void Disconnect(); vo

我在决定如何最好地使用依赖项注入(
DI
)构建双向对象管道时遇到了一些困难

我目前正在将
Ninject
作为
DI
容器进行试验

它实际上比这更复杂,因为我正在考虑用适配器将两个管道绑定在一起

这两条管道由以下接口对(
ITransport
ITransportSink
)和(
IMessageProcessor
IMessageProcessorSink
)定义:

public interface ITransport {
  void Connect();
  void Disconnect();
  void Send(byte[] buffer)
  void Receive();
}

public interface ITransportSink {
  void OnConnected();
  void OnDisconnected();
  void OnSent();
  void OnReceived(byte[] data);
}

public interface IMessageProcessor {
  void SendMessage(string message);
  void ReceiveMessage();
}

public interface IMessageProcessorSink {
  void OnMessageSent();
  void OnMessageReceived(string message);
}

public class TcpTransport : ITransport {
  public TcpTransport(
    ISocket socket, 
    ITransportSink sink,
    ...
  ) { }
}

public class Program : IMessageProcessorSink {
  void Run() {
    // Set up serializer as an adapter between transports and message processors
    var serializer = new MessageSerializer();
    var tcpTransport = new TcpTransport(socket, serializer);
    serializer.SetTransport(tcpTransport);
    serializer.SetMessageSink(this);
  }

  void OnMessageReceived(string message) {
    Console.Writeline("Received message {0}", message);
  }
}

public class MessageSerializer : ITransportSink, IMessageProcessor {
  public void OnReceived(byte[] data) {
    // Deserializes message and raises IMessageProcessorSink::OnMessageReceived
    var message = Deserialize(data);
    m_processorSink.OnMessageReceived(message);
  }

  public void SendMessage(string message) {
    // Serializes message to byte and calls ITransport::Send
    byte[] data = Serialize(message);
    m_transport.Send(data);
  }
}

var program = new Program();
program.Run();
问题:
如何最好地使用
Ninject
创建管道和适配器(MessageSerializer)

问题(高级):
现在考虑在MeaseSerialAlgisher连接的管道中可以有多个ITANCANT和多个IDESCAGE处理器。 使用:

m_kernel.Get<IEnumerable<ITransport>>() 
然后,安装程序将类似于:

var transportPipelineFactory = m_kernel.Get<ITransportPipelineFactory>();
var messagePipelineFactory = m_kernel.Get<IMessageProcessorPipelineFactory>();

var transportPipeline = transportPipelineFactory.CreatePipeline();
var messageProcessorPipeline = messagePipelineFactory.CreatePipeline();

var serializer = new MessageSerializer();
transportPipeline.Append(serializer);
messageProcessorPipeline.InsertAt(0,serializer);
var transportPipelineFactory=m_kernel.Get();
var messagePipelineFactory=m_kernel.Get();
var transportPipeline=transportPipelineFactory.CreatePipeline();
var messageProcessorPipeline=messagePipelineFactory.CreatePipeline();
var serializer=new MessageSerializer();
transportPipeline.Append(序列化程序);
messageProcessorPipeline.InsertAt(0,序列化程序);
在这一点上,我编写了太多的手动接线代码,以至于
DI
容器似乎没有多大帮助。是否有
DI
容器特性或绑定可以在这里提供帮助


我觉得要么设计错误,要么这不是
DI
容器想要解决的问题。

花了我一段时间,但我找到了一种方法让它工作。 诀窍是将配置逻辑包装在更高级别的概念对象构造函数中:

public class AggregatePipeline
{
    private ITransportPipeline m_transportPipelines;
    private IMessageProcessorPipeline m_messagePipeline;
    private MessageSerializer m_serializer;

    public AggregatePipeline(
        ITransportPipeline transportPipeline,
        IMessageProcessorPipeline messagePipeline,
        MessageSerializer serializer)
    {
        transportPipeline.Append(serializer);
        messagePipeline.Prepend(serializer);

        m_transportPipeline = transportPipeline;
        m_messagePipeline = messagePipeline;
        m_serializer = serializer;
    }
}
因为每个项都是构造函数参数,所以不需要显式调用内核。 添加两个绑定:

Bind<AggregatePipeline>().ToSelf()
    .WithConstructorArgument("transportPipeline", (ctx) =>
        {
            return ctx.Kernel.Get<ITransportPipelineFactory>().CreatePipeline();
        })
    .WithConstructorArgument("messagePipeline", (ctx) =>
        {
            return ctx.Kernel.Get<IMessageProcessorPipelineFactory>().CreatePipeline();
        });

Bind<MessageSerializer>().ToSelf();
Bind().ToSelf()
.WithConstructorArgument(“运输管道”(ctx)=>
{
返回ctx.Kernel.Get().CreatePipeline();
})
.WithConstructorArgument(“messagePipeline”,(ctx)=>
{
返回ctx.Kernel.Get().CreatePipeline();
});
Bind().ToSelf();
然后通过内核创建外部对象:

m_kernel.Get<AggregatePipeline>();
m_kernel.Get();
似乎解决了没有服务位置反模式的问题

m_kernel.Get<AggregatePipeline>();