C# 深层自动解析

C# 深层自动解析,c#,dependency-injection,autofac,resolve,C#,Dependency Injection,Autofac,Resolve,我很难将autofac集成到我的应用程序中 我的应用程序与其他应用程序集成,当连接到另一个应用程序时,它由一个合适的“协议”对象进行维护 我有一个层,由它自己的线程运行并处理连接请求。对于每种请求,都会创建不同的协议(不同的协议对象) 我的协议对象已设置密钥并注册为协议。也, 每个服务都使用密钥注册,因为每个协议都使用从同一接口继承的不同类型。当然,所有这些都被注册为PerDependency(尽管我并不真正理解这个生命周期与PerScope之间的区别,但我非常感谢您的解释) 这是我糟糕的课堂:

我很难将autofac集成到我的应用程序中

我的应用程序与其他应用程序集成,当连接到另一个应用程序时,它由一个合适的“协议”对象进行维护

我有一个层,由它自己的线程运行并处理连接请求。对于每种请求,都会创建不同的协议(不同的协议对象)

我的协议对象已设置密钥并注册为协议。也, 每个服务都使用密钥注册,因为每个协议都使用从同一接口继承的不同类型。当然,所有这些都被注册为PerDependency(尽管我并不真正理解这个生命周期与PerScope之间的区别,但我非常感谢您的解释)

这是我糟糕的课堂:

public class ProtocolsLayer : Layer
{
    private IFrameworkDependencyResolver _resolver;
    private IConfigurationService _configService;

    public ProtocolsLayer(IFrameworkDependencyResolver resolver, IConfigurationService configurationService)
    {
        _resolver = resolver;
        _configService = configurationService;
    }

    void HandleConnection1()
    {
        // What I have at the moment (terrible):

        // Resolve the fitting services (All keyed - key is received by the type, Resolve and ResolveWithParameters used here are my wrappers)
        var agent = _resolver.Resolve<IFramingAgent>(typeof(Protocol1FramingAgent));

        var algo = _resolver.Resolve<IFramingAlgorithm>(typeof(Protocol1FramingAlgorith));

        var parser = _resolver.Resolve<IFramingParser>(typeof(Protocol1FramingParser));

        // A parameter I get and pass to each protocol at runtime
        var protocolConfig = _configService.GetConfig<Protocol1Configuration>();

        // Finally resolve the protocol with it's parameters:

        protocol = _resolver.ResolveWithParameters<IProtocol>(typeof(Protocol1), new List<object>{
            agent, resolver, parser, protocolConfig 
        });

        //...

        // Theres gotta be a better way!! 
    }

    void HandleConntection2()
    {
        // Same as in protocol1
    }

    void HandleConnection3()
    {
        // Same as in protocol1
    }
}
public类ProtocolsLayer:Layer
{
专用IFrameworkDependencyResolver\u解析器;
专用IConfigurationService\u配置服务;
公共协议杀手(IFrameworkDependencyResolver解析器,IConfigurationService配置服务)
{
_分解器=分解器;
_configService=configurationService;
}
void HandleConnection1()
{
//我目前的情况(糟糕):
//解析fitting services(所有keyed-key都由type接收,这里使用的Resolve和ResolveWithParameters是我的包装器)
变量代理=_resolver.Resolve(typeof(Protocol1FramingAgent));
var algo=_resolver.Resolve(typeof(Protocol1FramingAlgorith));
var parser=_resolver.Resolve(typeof(Protocol1FramingParser));
//我在运行时获取并传递给每个协议的参数
var protocolConfig=_configService.GetConfig();
//最后,使用其参数解析协议:
protocol=_resolver.ResolveWithParameters(typeof(Protocol1),新列表{
代理,解析器,解析器,protocolConfig
});
//...
//一定有更好的办法!!
}
void HandleConntection2()
{
//与协议1相同
}
void HandleConnection3()
{
//与协议1相同
}
}
请记住,我不想引用autofac,这意味着我不能使用我听说过的IIndex


谢谢

应该让依赖项注入框架管理实例

您使用
ResolveWithParameter
方法,其中这些参数已由依赖项注入框架解析。这不是必需的,您可以让框架为您找到依赖项:

如果
Protocol1
需要一个命名参数,您可以在注册过程中指定它

builder.Register(c => c.Resolve<IConfigurationService>()
                       .GetConfig<Protocol1Configuration>())
       .As<Protocol1Configuration>(); 

builder.RegisterType<Protocol1>()
       .Named<IProtocol1>(nameof(Protocol1))
       .WithParameter((pi, c) => pi.ParameterType == typeof(IFramingAgent), 
                      (pi, c) => c.ResolveNamed<IFramingAgent>(nameof(Protocol1))
       .WithParameter((pi, c) => pi.ParameterType == typeof(IFramingAlgorithm), 
                      (pi, c) => c.ResolveNamed<IFramingAlgorithm>(nameof(Protocol1));
builder.RegisterType<FramingAgentProtocol1>()
       .Named<IFramingAgent>(nameof(Protocol1));
builder.RegisterType<FramingAlgorithmProtocol1>()
       .Named<IFramingAlgorithm>(nameof(Protocol1));
如果您不想为整个应用程序引入对
IIndex
的依赖,可以引入将在运行时定义的
IProtocolFactory
,并仅为注册项目创建实现

在运行时项目中:

public interface IProtocolFactory
{
    IProtocol Create(String protocolName)
}
public class ProtocolFactory : IProtocolFactory
{

    public ProtocolFactory(IIndex<String, IProtocol> index)
    {
        this._index = index; 
    }

    private readonly IIndex<String, IProtocol> _index; 

    public IProtocol Create(String protocolName)
    {
        return this._index[typeof(TProtocol).Name]; 
    }
}    
在您的注册项目中:

public interface IProtocolFactory
{
    IProtocol Create(String protocolName)
}
public class ProtocolFactory : IProtocolFactory
{

    public ProtocolFactory(IIndex<String, IProtocol> index)
    {
        this._index = index; 
    }

    private readonly IIndex<String, IProtocol> _index; 

    public IProtocol Create(String protocolName)
    {
        return this._index[typeof(TProtocol).Name]; 
    }
}    
您还可以注册一个名为resolve
IProtocol的
Func

ProtocolsLayer
将如下所示:

public class ProtocolsLayer 
{
    public ProtocolsLayer(IProtocolFactory protocolFactory)
    {
        this._protocolFactory = protocolFactory; 
    }

    private readonly IProtocolFactory _protocolFactory;

    public void HandleConnection1()
    {
        IProtocol protocol = this._protocolFactory.Create("Protocol1"); 
    }
}
public class ProtocolsLayer 
{
    public ProtocolsLayer(Func<String, IProtocol> protocolFactory)
    {
        this._protocolFactory = protocolFactory; 
    }

    private readonly Func<String, IProtocol> _protocolFactory;

    public void HandleConnection1()
    {
        IProtocol protocol = this._protocolFactory("Protocol1"); 
    }
}
builder.Register(c => (String namedProtocol) => c.ResolveNamed<IProtocol>(namedProtocol)
       .As<Func<String, IProtocol>>(); 
公共类协议杀手
{
公共协议制定者(Func协议工厂)
{
这个._protocolFactory=protocolFactory;
}
私有只读Func_协议工厂;
公共无效HandleConnection1()
{
IProtocol协议=本协议工厂(“协议1”);
}
}
注册方式如下:

public class ProtocolsLayer 
{
    public ProtocolsLayer(IProtocolFactory protocolFactory)
    {
        this._protocolFactory = protocolFactory; 
    }

    private readonly IProtocolFactory _protocolFactory;

    public void HandleConnection1()
    {
        IProtocol protocol = this._protocolFactory.Create("Protocol1"); 
    }
}
public class ProtocolsLayer 
{
    public ProtocolsLayer(Func<String, IProtocol> protocolFactory)
    {
        this._protocolFactory = protocolFactory; 
    }

    private readonly Func<String, IProtocol> _protocolFactory;

    public void HandleConnection1()
    {
        IProtocol protocol = this._protocolFactory("Protocol1"); 
    }
}
builder.Register(c => (String namedProtocol) => c.ResolveNamed<IProtocol>(namedProtocol)
       .As<Func<String, IProtocol>>(); 
builder.Register(c=>(字符串namedProtocol)=>c.ResolveNamed(namedProtocol)
.As();

但是我不推荐这个解决方案,因为
Func protocolFactory
依赖项的意图不明确。拥有
IProtocolFactory
接口使依赖项目标易于理解。

Cyril谢谢!你能更详细地解释一下这个IProtocolFactory会是什么样子吗?这听起来是一个理想的解决方案me@S.Peter我编辑了我的帖子,加入了一个
IProtocolFactory
sample我怎么能使用它而不是不暴露于IIndex
IIndex
,它只是被引用Autofac的项目所知哦,我明白了,另一个问题是没有名字我怎么做?因为名字以后可能会改变。