如何配置Autofac容器,以便根据operation-parameter(请求对象)的属性值解析WCF服务的依赖关系?
例如,鉴于此数据合同......
[DataContract]
public class MyRequest
{
[DataMember]
public bool MyBool { get; set; }
}
此WCF服务......
public class MyWcfService : IWcfService
{
private IService m_service;
public MyWcfService(IService service)
{
m_service = service;
}
public virtual MyResponse Operation(MyRequest request) { }
}
和这些依赖...
public interface IService { }
public class TypeA : IService { }
public class TypeB : IService { }
我希望容器在MyBool等于true时解析TypeA,否则解决TypeB。这个功能可用吗?我应该以不同的方式解决问题吗?
约束:
答案 0 :(得分:5)
有几种方法可以实现这一目标。其中一种方法是使用IIndex<K,V>
。它是内置的“查找”功能,可在基于密钥的服务实现之间进行选择。您可以在Autofac的wiki page上找到更多信息。示例代码可能如下所示:
// 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];
}
}
另一种方法是使用元数据功能。有关wiki page的更多信息。
答案 1 :(得分:1)
选项1 - 使用Autofac:
创建服务实例的Autofac实例提供程序不使用或传递操作的消息。这是Autofac中的latest implementation of the method。请注意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);
}
}
因此,要使用现有的Autofac代码获得所需的行为,您需要使用构造函数注入以外的其他内容(例如@Alexandr Nikitin's solution)将依赖项注入到类中。这是合理的,但我同意“不爱它”的评论。
选项2 - 自定义IInstanceProvider:
编写自定义WCF IInstanceProvider是一个合理的选择,但它将是很多代码。
好消息是code in Autoface.Integration.WCF是一个很好的例子,你可以将你的实现插入到Autofac中。
坏消息是Autofac.Integration.WCF代码本身不使用依赖注入。例如AutofacDependencyInjectionServiceBehavior
直接调用var instanceProvider = new AutofacInstanceProvider(_rootLifetimeScope, _serviceData)
。因此,您必须实施AutofacInstanceProvider
,AutofacDependencyInjectionServiceBehavior
,AutofacHostFactory
以及更多内容的替换。然后,您需要为AutofacInstanceContext
创建一个扩展名,以包含从邮件中读取的信息。它的代码很多。
如果您打算使用自定义IInstanceProvider,我建议您阅读Carlos Figueira的博客: