WCF Unity






2.38/5 (8投票s)
该项目旨在将 WCF、依赖注入和策略注入结合使用。
引言
该项目展示了如何利用 Unity 容器用于 WCF。Unity 和策略注入应用程序块在此项目中协同工作。因此,WCF 服务可以实现依赖注入和策略注入。我假设类型定义位于不同的配置文件中。这样可以避免配置文件的复杂性,并为项目的实现提供独立性。
使用代码
Unity 容器在 WCF 中的最佳应用方式是使用实例提供程序的 Service Lifetime Controller 接口。首先,我编写了一个实例提供程序来支持依赖注入。
public class DependencyInjectionInstanceProvider : IInstanceProvider {
private void InitContainer(string dependencyFile, string containerName) {
string currentContainerKey = GetDependencyKey(dependencyFile, containerName);
if (!containers.ContainsKey(currentContainerKey)) {
lock (syncRoot) {
if (!containers.ContainsKey(currentContainerKey)) {
containers[currentContainerKey] = currentContainer =
new UnityContainer();
ExeConfigurationFileMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = dependencyFile;
System.Configuration.Configuration config
= ConfigurationManager.OpenMappedExeConfiguration(map,
ConfigurationUserLevel.None);
UnityConfigurationSection section
= (UnityConfigurationSection)config.GetSection("unity");
section.Containers[containerName].Configure(currentContainer);
currentContainer.AddNewExtension<PolicyInjectionExtension>();
}
}
} else {
currentContainer = containers[currentContainerKey];
}
}
DependencyInjectionInstanceProvider 需要两个参数:类型定义中配置的依赖文件和配置文件中的容器名称。每个容器只出现一次并保存。最后,这些对象将提供给 PolicyInjectionExtansion。PolicyInjectionExtansion 仅在 EnterpriseLibrary.PolicyInjection.ObjectBuilder 命名空间的策略和策略下注册。最后,需要将依赖注入提供程序作为新的服务行为来实现。
public class DependencyInjectionServiceBehavior : Attribute, IServiceBehavior {
public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase) {
foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers) {
ChannelDispatcher cd = cdb as ChannelDispatcher;
if (cd != null) {
foreach (EndpointDispatcher ed in cd.Endpoints) {
ed.DispatchRuntime.InstanceProvider =
new DependencyInjectionInstanceProvider(
serviceDescription.ServiceType, configFile, containerName);
}
}
}
}
现在,就可以同时使用 WCF 和 Unity 依赖注入了。
static void Main(string[] args) { ServiceHost hostA = null, hostB = null; try { hostA = new ServiceHost(typeof(ServiceA)); hostB = new ServiceHost(typeof(ServiceB)); hostA.Open(); hostB.Open(); [ServiceBehavior] public class ServiceA : IServiceAContract { public ServiceA() { } private IServiceBContract serviceB; private IServiceC serviceC; [InjectionConstructor] public ServiceA(IServiceBContract serviceB) { Console.WriteLine("Build up Service A"); this.serviceB = serviceB; Console.WriteLine("Service A constructor calling to serviceB.OperationD"); this.serviceB.OperationD("test1", "test2"); } [Dependency] public IServiceC ServiceC { set { serviceC = value; Console.WriteLine("IServiceC injected to ServiceA parameter "); } } public class ServiceB : IServiceBContract { public ServiceB() { } private IServiceC serviceC; [InjectionConstructor] public ServiceB(IServiceC serviceC) { Console.WriteLine("Build up Service B "); this.serviceC = serviceC; Console.WriteLine("Service B constructor calling to serviceC.OperationG"); this.serviceC.OperationG("test"); this.serviceC.OperationG("test"); }许多流行的应用程序架构师,如 Smart/Web Client Software Factory,都有自己的对象构建器。但对于 WCF 而言,还没有像 SCSF/WCSF 这样的应用程序架构师。这是一个缺失。