本文介绍了Autofac-如何使用参数创建生成的工厂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Autofac创建一个生成的"工厂,该工厂将基于枚举参数实时解决依赖关系.

I am trying to create with Autofac a 'generated' factory that will resolve dependencies in real-time based on an enum parameter.

给出以下接口/类 :

Given the following interfaces/classes:

public delegate IConnection ConnectionFactory(ConnectionType connectionType);

public enum ConnectionType
{
    Telnet,
    Ssh
}

public interface IConnection
{
    bool Open();
}

public class SshConnection : ConnectionBase, IConnection
{
    public bool Open()
    {
        return false;
    }
}

public class TelnetConnection : ConnectionBase, IConnection
{
    public bool Open()
    {
        return true;
    }
}

public interface IEngine
{
    string Process(ConnectionType connectionType);
}

public class Engine : IEngine
{
    private ConnectionFactory _connectionFactory;

    public Engine(ConnectionFactory connectionFactory)
    {
        _connectionFactory = connectionFactory;
    }

    public string Process(ConnectionType connectionType)
    {
        var connection = _connectionFactory(connectionType);

        return connection.Open().ToString();
    }
}

我想使用Autofac生成某种工厂,该工厂的方法可以接收一个参数:ConnectionType并返回正确的连接对象.

I'd like to use Autofac to generate some sort of factory that has a method that receives one parameter: ConnectionType and returns the correct connection object.

我从以下注册开始:

I started with the following registrations:

builder.RegisterType<AutoFacConcepts.Engine.Engine>()
    .As<IEngine>()
    .InstancePerDependency();

builder.RegisterType<SshConnection>()
    .As<IConnection>();
builder.RegisterType<TelnetConnection>()
    .As<IConnection>();

然后我继续使用不同的选项处理TelnetConnection/SshConnection注册:

I then continued to play with the TelnetConnection/SshConnection registrations with different options:

  1. 命名
  2. 键控
  3. 元数据

我找不到能够使我定义生成的工厂委托的注册的正确组合,该委托将返回正确的连接对象(用于ConnectionType.Ssh的SshConnection和用于ConnectionType.Telnet的TelnetConnection).

I couldn't find the correct combination of the registrations that will allow me to define a generated factory delegate that will return the correct connection object (SshConnection for ConnectionType.Ssh and TelnetConnection for ConnectionType.Telnet).

推荐答案

更新Engine类以使用Func<ConnectionType, IConnection>代替委托. Autofac 支持通过Func<T> 动态创建委托工厂.

Update the Engine class to take a Func<ConnectionType, IConnection> instead of the delegate. Autofac supports creating delegate factories on the fly via Func<T>.

public class Engine : IEngine
{
    private Func<ConnectionType, IConnection> _connectionFactory;

    public Engine(Func<ConnectionType, IConnection> connectionFactory)
    {
        _connectionFactory = connectionFactory;
    }

    public string Process(ConnectionType connectionType)
    {
        var connection = _connectionFactory(connectionType);

        return connection.Open().ToString();
    }
}

在注册时,请使用lambda来获取参数并返回正确的IConnection实例.

In your registration use a lambda that grabs up the parameter and returns the correct IConnection instance.

builder.Register<IConnection>((c, p) =>
{
    var type = p.TypedAs<ConnectionType>();
    switch (type)
    {
        case ConnectionType.Ssh:
            return new SshConnection();
        case ConnectionType.Telnet:
            return new TelnetConnection();
        default:
            throw new ArgumentException("Invalid connection type");
    }
})
.As<IConnection>();

如果连接本身需要依赖项,则可以在c参数上调用Resolve,以从当前调用上下文中解析它.例如,new SshConnection(c.Resolve<IDependency>()).

If the connection itself required a dependency you could call Resolve on the c parameter to resolve it from the current call context. For example, new SshConnection(c.Resolve<IDependency>()).

这篇关于Autofac-如何使用参数创建生成的工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 22:22