简体   繁体   English

Autofac WCF集成 - 根据请求数据解析依赖关系

[英]Autofac WCF Integration - Resolve dependencies based on request data

How can I configure an Autofac container so it resolves the dependencies of a WCF service based on properties values of the operation-parameter (request object)? 如何配置Autofac容器,以便它根据operation-parameter(请求对象)的属性值解析WCF服务的依赖关系?

For example, given this data contract... 例如,鉴于此数据合同......

[DataContract]
public class MyRequest
{
    [DataMember]
    public bool MyBool { get; set; }
}

this WCF service... 这个WCF服务......

public class MyWcfService : IWcfService
{
    private IService m_service;

    public MyWcfService(IService service)
    {
        m_service = service;
    }

    public virtual MyResponse Operation(MyRequest request) { }
}

and these dependencies... 和这些依赖...

public interface IService { }
public class TypeA : IService { }
public class TypeB : IService { }

I would like the container to resolve TypeA if MyBool equals true and TypeB otherwise. 如果MyBool等于true,我希望容器解析TypeA,否则解决TypeB。 Is that feature available? 这个功能可用吗? Should I approach the problem differently? 我应该以不同方式解决问题吗?

Constraints: 约束:

  • Avoiding the Autofac.Extras.Multitenant package is a plus. 避免使用Autofac.Extras.Multitenant包是一个优点。
  • Keeping the signature of the service constructor unchanged is also desired. 还希望保持服务构造函数的签名不变。 (See my answer below) (见下面的答案)

There are a few ways to achieve this. 有几种方法可以实现这一目标。 One of the ways is to use IIndex<K,V> . 其中一种方法是使用IIndex<K,V> It's built-in "lookup" feature that chooses between service implementations based on a key. 它是内置的“查找”功能,可在基于密钥的服务实现之间进行选择。 You can find more info on Autofac's wiki page . 您可以在Autofac的维基页面上找到更多信息。 An example code could look like: 示例代码可能如下所示:

// Register your dependency with a key, for example a bool flag
builder.RegisterType<TypeA>().Keyed<IService>(true);
builder.RegisterType<TypeB>().Keyed<IService>(false);

// Your service could look like:
public class MyWcfService
{
    private readonly IIndex<bool, IService> _services;

    // Inject IIndex<Key,Value> into the constructor, Autofac will handle it automatically
    public MyWcfService(IIndex<bool, IService> services)
    {
        _services = services;
    }

    public virtual void Operation(MyRequest request)
    {
        // Get the service that you need by the key
        var service = _services[request.MyBool];
    }
}

Another approach is to use Metadata feature. 另一种方法是使用元数据功能。 More information on wiki page . 有关wiki页面的更多信息。

Option 1 - Using Autofac: 选项1 - 使用Autofac:

The Autofac instance provider that creates your service instance does not use or pass along the operation's message. 创建服务实例的Autofac实例提供程序不使用或传递操作的消息。 Here's the latest implementation of the method in Autofac. 这是Autofac 中该方法最新实现 Notice the message parameter is unused. 请注意, message参数未使用。

public class AutofacInstanceProvider : IInstanceProvider
{
    // lots of code removed...

    public object GetInstance(InstanceContext instanceContext, Message message)
    {
        if (instanceContext == null)
        {
            throw new ArgumentNullException("instanceContext");
        }
        var extension = new AutofacInstanceContext(_rootLifetimeScope);
        instanceContext.Extensions.Add(extension);
        return extension.Resolve(_serviceData);
    }
}

So to get the behavior you want with existing Autofac code, you'll need to inject the dependency into your class using something other than constructor injection , which is @Alexandr Nikitin's solution . 因此,要使用现有的Autofac代码获得所需的行为,您需要使用构造函数注入之外的其他内容将依赖项注入到类中 ,这是@Alexandr Nikitin的解决方案 This is reasonable, but I agree with the comment "not loving it". 这是合理的,但我同意“不爱它”的评论。

Option 2 - A Custom IInstanceProvider: 选项2 - 自定义IInstanceProvider:

Writing a custom WCF IInstanceProvider is a reasonable option, but it will be a lot of code. 编写自定义WCF IInstanceProvider是一个合理的选择,但它将是很多代码。

The good news is that the code in Autoface.Integration.WCF is a nice example and you could plug your implementation into Autofac. 好消息是Autoface.Integration.WCF中的代码是一个很好的例子,你可以将你的实现插入到Autofac中。

The bad news is that Autofac.Integration.WCF code doesn't itself use dependency injection. 坏消息是Autofac.Integration.WCF代码本身不使用依赖注入。 For example AutofacDependencyInjectionServiceBehavior directly calls var instanceProvider = new AutofacInstanceProvider(_rootLifetimeScope, _serviceData) . 例如, AutofacDependencyInjectionServiceBehavior直接调用var instanceProvider = new AutofacInstanceProvider(_rootLifetimeScope, _serviceData) As a result you'll you have to implement a replacement for AutofacInstanceProvider , AutofacDependencyInjectionServiceBehavior , AutofacHostFactory , and probably more. 因此,您必须实现AutofacInstanceProviderAutofacDependencyInjectionServiceBehaviorAutofacHostFactory以及更多内容的替换。 Then you'll need to create an extension for the AutofacInstanceContext to contain the information read from the message. 然后,您需要为AutofacInstanceContext创建一个扩展,以包含从消息中读取的信息。 Its a lot of code. 它的代码很多。

If you are going to do the custom IInstanceProvider I suggest reading up on Carlos Figueira's blog: 如果您打算使用自定义IInstanceProvider,我建议您阅读Carlos Figueira的博客:

  1. WCF Extensibility – IInstanceProvider - for good background WCF可扩展性 - IInstanceProvider - 为良好的背景
  2. WCF Extensibility – Message Inspectors - Search for the section that starts with WCF Message objects can only be “consumed once". You'll need to follow these rules when inspecting the message. WCF可扩展性 - 消息检查器 - 搜索以WCF开头的部分消息对象只能“消耗一次”。检查消息时,您需要遵循这些规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何解析Autofac中的依赖项列表? - How to resolve list of dependencies in Autofac? Autofac Wcf-根据SOAP请求中的数据注入服务 - Autofac Wcf - Inject service depending on data within SOAP Request 如何使用Autofac来解析Nancy创建的子生命周期范围中的类型的每个请求依赖项的实例 - How to use Autofac to resolve instance per request dependencies for types in a child lifetime scope created by Nancy 使用Autofac解决继承类的依赖关系 - Resolve dependencies from inherited classes with Autofac Autofac-解决单独程序集的WebApi控制器中的依赖项 - Autofac - Resolve dependencies in WebApi controllers of seperate assemblies 解决OWIN Startup类中的Autofac依赖项 - Resolve Autofac dependencies in OWIN Startup class Autofac:注入注入的对象(解决困难的依赖关系) - Autofac: injecting in injected object (resolve difficult dependencies) Hangfire Autofac集成无法解析具有注册依赖项的服务 - Hangfire Autofac integration is not able to resolve service with registred dependency Autofac:基于条件/参数解析以删除要实例化的开关语句 - Autofac: Resolve Based on a Condition/Parameter to Remove Switch Statements for Instantiation 如何使用Autofac根据用户上下文解析组件 - How to resolve component based on user context using Autofac
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM