65.9K
CodeProject 正在变化。 阅读更多。
Home

WCF Unity

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.38/5 (8投票s)

2008 年 6 月 24 日

CPOL

1分钟阅读

viewsIcon

50907

downloadIcon

732

该项目旨在将 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 这样的应用程序架构师。这是一个缺失。
© . All rights reserved.