WCF+Autofac 实现构造函数依赖注入

1.新建一个项目

2.要对WCF服务实现Autofac注入,需要实现2个接口,IInstanceProviderIServiceBehavior,并让实现IServiceBehavior的类成为一个Attribute(继承自Attribute),然后加在WCF服务实现类上,就可以实现WCF的构造函数依赖注入。

首先现接口IServiceBehavior,新建一个类IocServiceBehavior

namespace XiaoYaoDiJun_WCF_Template.IOC
{
    public class IocServiceBehavior : Attribute, IServiceBehavior
    {
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }

        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints,
            BindingParameterCollection bindingParameters)
        {
            if(serviceHostBase.State== CommunicationState.Opened)return;//第一次进入时State是Opening。第二次进入时State是opened,如果继续往下走,程序就会出错
            foreach (var item in serviceHostBase.ChannelDispatchers)
            {
                var dispatcher = item as ChannelDispatcher;
                if (dispatcher != null)
                {
                    foreach (var it in dispatcher.Endpoints)
                    {
                        it.DispatchRuntime.InstanceProvider = new
                          IocInstanceProvider(serviceDescription.ServiceType);
                    }
                }
            }
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {

        }
    }
}

首先现接口IInstanceProvider,新建一个类IocInstanceProvider

namespace XiaoYaoDiJun_WCF_Template.IOC
{
    public class IocInstanceProvider : IInstanceProvider
    {
        Type serviceType;
        IContainer container;
        public IocInstanceProvider(Type _serviceType)
        {
            try
            {
                serviceType = _serviceType;
                var build = new ContainerBuilder();
                //注册wcf服务,Test_Template服务名称
                build.RegisterType(typeof(Test_Template));
                //注册接口
                RegisterBuilder(build);

                container = build.Build();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }
        //对业务逻辑层进行注册
        private void RegisterBuilder(ContainerBuilder build)
        {
            build.RegisterType<TestBll>().As<ITestBll>();
        }

        public object GetInstance(InstanceContext instanceContext)
        {
            return GetInstance(instanceContext, null);
        }

        public object GetInstance(InstanceContext instanceContext, Message message)
        {
            return container.Resolve(serviceType);
        }

        public void ReleaseInstance(InstanceContext instanceContext, object instance)
        {
            if (instance is IDisposable)
                ((IDisposable)instance).Dispose();
        }
    }
}

3.控制台启动方式,此时不需要在服务类中写启动方法

namespace XiaoYaoDiJun_WCF_Template
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var host = new ServiceHost(typeof(Test_Template));
                host.Open();
                Console.WriteLine("服务已经开启");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

4.windows服务启动方式,此时需要在服务类中写启动方法

   partial class Wcf_ProjectService : ServiceBase
    {
        public Wcf_ProjectService()
        {
            InitializeComponent();
        }

        private ServiceHost host = null;
        protected override void OnStart(string[] args)
        {
            if (host != null) return;
            host = new ServiceHost(typeof(Test_Template));
            host.Open();
        }

        protected override void OnStop()
        {
          if(host.State!=CommunicationState.Closed)host.Close();
        }
    }
namespace XiaoYaoDiJun_WCF_Template
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //Wcf_ProjectService服务名称
                var serviceToRun = new ServiceBase[] {new Wcf_ProjectService() };
                ServiceBase.Run(serviceToRun);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

2种方式都可以启动服务!

参考文章:轻松实现WCF服务的构造函数依赖注入 

              Autofac 解释第一个例子 《第一篇》

              Autofac 组件、服务、自动装配 《第二篇》

              通过配置的方式Autofac 《第三篇》

原文地址:https://www.cnblogs.com/xiaoyaodijun/p/6780732.html