我读了Jimmy Bogard的这篇文章,然后就想到了如何在服务上创建依赖项注入。我阅读了这两篇文章:http://blogs.planbsoftware.co.nz/?p=492和http://lostechies.com/jimmybogard/2008/07/30/integrating-structuremap-with-wcf/。
因此,阅读本文后,我的问题是,在哪里编写在那里描述的那些类(StructureMapInstanceProvider,StructureMapServiceBehavior,StructureMapServiceHost,StructureMapServiceHostFactory)。我应该在服务上还是在服务的主机上写那些?另一个问题是在哪里配置服务?在主机的global.asax中还是在服务的global.asax中?
有人可以向我解释吗?
最佳答案
一起讨论WCF和StructureMap的文章比较古老。我创建了一个使用WCF和StructureMap的最小应用程序,可以在GitHub中找到它。
说明
WCF通过IInstanceProvider
接口创建实例,因此我们需要创建一个自定义实例提供程序,该提供程序通过StructureMap创建实例。此实例提供者使用容器来解析请求的类型:
public class StructureMapInstanceProvider : IInstanceProvider
{
private readonly IContainer _container;
private readonly Type _type;
public StructureMapInstanceProvider(IContainer container, Type type)
{
_container = container;
_type = type;
}
public object GetInstance(InstanceContext instanceContext)
{
return _container.GetInstance(_type);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return GetInstance(instanceContext);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
_container.Release(instance);
}
}
通过设置
InstanceProvider
类的DispatchRuntime
,每个端点可以具有自己的实例提供程序。这通常是完成的。通常,这是从IServiceBehavior
中的服务行为(ApplyDispatchBehavior
)内部完成的。public class StructureMapServiceBehavior : IServiceBehavior
{
private readonly IContainer _container;
public StructureMapServiceBehavior(IContainer container)
{
_container = container;
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (var channelDispatcher in serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>())
{
foreach (var ed in channelDispatcher.Endpoints)
ed.DispatchRuntime.InstanceProvider = new StructureMapInstanceProvider(_container, serviceDescription.ServiceType);
}
}
}
需要将该行为添加到
ServiceHost
,以便将其应用于该主机内的所有服务:serviceHost.Description.Behaviors.Add(new StructureMapServiceBehavior(container));
现在将通过StructureMap创建服务,您可以在服务中使用依赖项注入。该解决方案不使用任何静态变量或工厂模式(如我所见的其他一些示例所示)。
嵌套容器
当服务的
InstanceContextMode
设置为PerCall
或PerSession
时,您可能需要嵌套容器。您需要在IInstanceProvider.GetInstance
调用中创建这些嵌套容器,然后将嵌套容器放置在IInstanceProvider.ReleaseInstance
中。为了确保可以关联GetInstance
和ReleaseInstance
,可以将其他信息添加到实例上下文中(通过Extensions
属性。您可以在commit中找到所需的更改。)单身人士服务(小酒馆)
在
ServiceHost
的构造函数中已经创建了单例,因此您不能使用行为来更改创建。如果单例具有默认构造函数(并且IoC服务通常不具有这些构造函数),则只能在WCF中创建它们。如果要将服务主机与StructureMap和单例一起使用,则可以将单例直接传递到容器:using (var container = Register())
{
var singleton = container.Resolve<HelloWcfServer>();
using (var host = new ServiceHost(singleton, Settings.BaseUri))
{
// ...
}
}
关于c# - 使用WCF为IoC(依赖注入(inject))配置StructureMap,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26480620/