IoC,工厂和构造函数参数

Lar*_*sbj 6 .net c# inversion-of-control autofac

我是IoC和DI的初学者.我希望能够使用autofac(或任何其他合适的.NET IoC工具)动态解析连接和连接工厂.

一个场景可能是将连接实现更改为另一个具有更多跟踪设施的实现.

当我将DI和IoC应用于下面的代码时,我在构造函数等中得到了一堆namedParameter.连接工厂返回一个带有唯一端口的新连接(愚蠢的例子,只是为了表明我需要在工厂中保持某种状态)

我想我可以使用属性注入的IP和端口范围,但是这样,我不能保证连接将具有IP或端口,这是构造函数的要点.此外,命名参数也使我依赖于参数的名称.

想法,模式,IoC指针非常感谢!

更新:

更具体:如何将连接类更改为可注入?我应该选择房产吗?或者我能做的任何技巧都可以通过构造函数参数获得更加类型安全的解析?

public interface IConnection {
     void Open();
     void Close();
     string Execute(string command);
}

public interface IConnectionFactory {
     IConnection CreateConnection();
}

public class Connection : IConnection {
   ...
   public Connection(String ip, int port) {
     _ip = ip;
     _port = port;
   }

   public string Execute() {}   
   public void Open() {}
   public void Close() {}
}


public class ConnectionFactory : IConnectionFactory {
    //How would I resolve this?
    public ConnectionFactory(string ip, int fromPort) {
        ...
    }
    public IConnection CreateConnection()  {
        //How would I resolve this? 
        return new Connection(ip, fromPort++);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,用法:

//Register
builder.RegisterType<Connection>().As<IConnection>();
builder.RegisterType<ConnectionFactory>().As<IConnectionFactory>().SingleInstance();
...

var connection = container.Resolve<IConnectionFactory>(
      new NamedParameter("ip", "127.0.0.1"), 
      new NamedParameter("fromPort", 80).CreateConnection());
Run Code Online (Sandbox Code Playgroud)

Bry*_*tts 6

在resolve-time传递构造函数参数的另一种方法是在注册函数中对这些参数进行编码:

builder
.Register(c => new ConnectionFactory("127.0.0.1", 80))
.As<IConnectionFactory>()
.SingleInstance();
Run Code Online (Sandbox Code Playgroud)

只要需要创建连接工厂实例,Autofac就会使用该功能.

由于我们配置ConnectionFactorySingleInstance,它将在所有依赖的组件之间共享IConnectionFactory.这意味着ConnectionFactory需要在调用之间保持自己的状态CreateConnection:

public class ConnectionFactory : IConnectionFactory
{
    private int _fromPort;

    public ConnectionFactory(string ip, int fromPort)
    {
        ...
        _fromPort = fromPort;
    }

    public IConnection CreateConnection()
    {
        return new Connection(ip, _fromPort++);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你有一次性ConnectionFactory使用不同的IP,你可以使用命名注册:

builder
.Register(c => new ConnectionFactory("192.168.0.1", 80))
.Named<IConnectionFactory>("AlernateConnectionFactory")
.SingleInstance();
Run Code Online (Sandbox Code Playgroud)

如果希望组件使用该特定工厂而不是默认工厂,则可以使用以下ResolveNamed方法:

builder.Register(c => new Foo(c.ResolvedNamed<IConnectionFactory>("AlernateConnectionFactory")));
Run Code Online (Sandbox Code Playgroud)

这是一种以多种方式配置类型并在特定位置使用它的方便技术.