我正在使用Drew (with Source)提供的解决方案为WCF服务注入统一性。该解决方案通过实例提供程序和行为在内部向WCF添加扩展点。我能够使用我当前的项目。但我面对这种方法的问题是通过读取扩展项目中配置文件中的xml来动态初始化统一容器。
我正在使用与auto工厂的统一,并且不支持通过xml进行配置,并且寻找一种方法来使用代码来从服务项目中注册依赖项而不是xml。如何获得统一容器
任何想法。
答案 0 :(得分:2)
我想回答我自己的问题。
在当前的解决方案中,UnityInstanceProvider是硬编码的,所有我必须扩展初始化,以便我可以覆盖。
public class UnityBehaviorExtensionElement : BehaviorExtensionElement
{
protected override object CreateBehavior()
{
return new UnityServiceBehavior()
{
InstanceProviderFunc = InstanceProviderFunc(),
ContainerName = this.ContainerName,
ContextChannelEnabled = this.ContextChannelEnabled,
InstanceContextEnabled = this.InstanceContextEnabled,
OperationContextEnabled = this.OperationContextEnabled,
ServiceHostBaseEnabled = this.ServiceHostBaseEnabled
};
}
protected virtual Func<Type, string, UnityInstanceProvider> InstanceProviderFunc()
{
return (type, str) => new UnityInstanceProvider(type, str, UnityInstanceProvider.CreateUnityContainer);
}
}
UnityServiceBehavior: IServiceBehavior
{
....
public Func<Type, string, UnityInstanceProvider> InstanceProviderFunc;
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
...
foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
if (channelDispatcher != null)
{
foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
{
endpointDispatcher.DispatchRuntime.InstanceProvider =
InstanceProviderFunc(serviceDescription.ServiceType, this.ContainerName);
....
}
现在我可以在服务项目中定义自己的BehaviorExtensionElement并覆盖InstanceProviderFunc
public class TestClientBehaviorExtensionElement:UnityBehaviorExtensionElement
{
protected override Func<Type, string, UnityInstanceProvider> InstanceProviderFunc()
{
return (type, str) => new UnityInstanceProvider(type, str, CreateUnityContainer);
}
///<summary>
///</summary>
///<param name="containerName"></param>
///<returns></returns>
public IUnityContainer CreateUnityContainer(string containerName)
{
IUnityContainer unityContainer = new UnityContainer();
try
{
unityContainer.RegisterType<IOperationContextService, OperationContextService>(new UnityOperationContextLifetimeManager());
...
}
catch (Exception)
{
unityContainer.Dispose();
throw;
}
return unityContainer;
}