gpt4 book ai didi

c# - IoC、工厂和构造函数参数

转载 作者:太空狗 更新时间:2023-10-29 21:19:43 24 4
gpt4 key购买 nike

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

一个场景可能正在将连接实现更改为另一个具有更多跟踪功能的连接实现。

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

我想我可以对 IP 和端口范围使用属性注入(inject),但那样的话,我不能保证连接会有 IP 或端口,这是构造函数的要点。此外,命名参数也让我依赖于参数的名称。

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

更新:

更具体:如何将连接类更改为可注入(inject)的?我应该进行属性(property)注入(inject)吗?或者我可以使用任何技巧来使用构造函数参数进行类型更安全的解析?

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++);
}
}

现在,用法:

//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());

最佳答案

在解析时传递构造函数参数的替代方法是在注册函数中对这些参数进行编码:

builder
.Register(c => new ConnectionFactory("127.0.0.1", 80))
.As<IConnectionFactory>()
.SingleInstance();

Autofac 将在需要创建连接工厂实例时使用该函数。

由于我们将 ConnectionFactory 配置为 SingleInstance,它将在依赖于 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++);
}
}

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

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

当您希望组件使用该特定工厂而不是默认工厂时,您可以使用 ResolveNamed method :

builder.Register(c => new Foo(c.ResolvedNamed<IConnectionFactory>("AlernateConnectionFactory")));

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

关于c# - IoC、工厂和构造函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5161905/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com