未调用WCF自定义服务主机工厂

时间:2014-05-19 06:49:58

标签: wcf dependency-injection .net-4.5

我已经实现了一个可以正常工作的WCF服务库(.Net 4.5)。 然后我尝试使用自定义Servcie Host Factory实现Unity DI。调试应用程序我注意到我的工厂中的CreateServiceHost方法没有被调用,所以我的服务构造函数使用依赖项作为参数没有被调用,我得到这个错误:

“System.InvalidOperationException:提供的服务类型无法作为服务加载,因为它没有默认(无参数)构造函数。要解决此问题,请在类型中添加默认构造函数,或者传递实例对主持人的类型。“

我的自定义服务主机工厂:

namespace Amir.CodingChallenge.WcfService.Unity
{
    public class UnityServiceHostFactory : ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            UnityServiceHost serviceHost = new UnityServiceHost(serviceType,baseAddresses);


            // I register types in RegisterComponents method by coding.
            serviceHost.Container = UnityConfig.RegisterComponents();


            return serviceHost;
        }
    }
}

我的服务:

namespace Amir.CodingChallenge.WcfService
{
    public class MovieService : IMovieService
    {
        IShowService showService;

        public MovieService(IShowService showService)
        {
            this.showService = showService;
        }
        ...
    }
}

和App.Config:

<system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true">
      <serviceActivations>
        <add service="Amir.CodingChallenge.WcfService.MovieService"
             relativeAddress="./MovieService.svc"
             factory="Amir.CodingChallenge.WcfService.Unity.UnityServiceHostFactory"/>
      </serviceActivations>
    </serviceHostingEnvironment>
    <services>
      <service name="Amir.CodingChallenge.WcfService.MovieService">
        <endpoint address="" binding="wsHttpBinding" contract="Amir.CodingChallenge.WcfService.IMovieService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:49875/Amir.CodingChallenge.WcfService/MovieService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

“Amir.CodingChallenge.WcfService”是我的应用程序程序集名称。 我在配置中做错了吗?任何帮助将不胜感激。

我的其余代码将在下面提供更多信息。

UnityConfig类:

namespace Amir.CodingChallenge.WcfService.Unity
{
    public static class UnityConfig
    {
        static UnityContainer container;
        public static UnityContainer RegisterComponents()
        {
            if (container == null)
                container = new UnityContainer();

            RegisterTypes();

            return container;
        }

        private static void RegisterTypes()
        {
            container.RegisterType<IShowService, ShowService>(new HierarchicalLifetimeManager());
        }
    }
}

UnityServiceHost类:

namespace Amir.CodingChallenge.WcfService.Unity
{
    public class UnityServiceHost : ServiceHost
    {
        public UnityContainer Container { set; get; }

        public UnityServiceHost()
            : base()
        {
            Container = new UnityContainer();
        }

        public UnityServiceHost(Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses)
        {
            Container = new UnityContainer();
        }

        protected override void OnOpening()
        {
            if (this.Description.Behaviors.Find<UnityServiceBehavior>() == null)
                this.Description.Behaviors.Add(new UnityServiceBehavior(Container));

            base.OnOpening();
        }
    }
}

UnityServiceBehavior类:

namespace Amir.CodingChallenge.WcfService.Unity
{
    public class UnityServiceBehavior : IServiceBehavior
    {
        public UnityInstanceProvider InstanceProvider { get; set; }
        private ServiceHost serviceHost = null;

        public UnityServiceBehavior()
        {
            InstanceProvider = new UnityInstanceProvider();
        }

        public UnityServiceBehavior(UnityContainer unity)
        {
            InstanceProvider = new UnityInstanceProvider();
            InstanceProvider.Container = unity;
        }

        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)
                    {
                        InstanceProvider.ServiceType = serviceDescription.ServiceType;
                        ed.DispatchRuntime.InstanceProvider = InstanceProvider;
                    }
                }
            }
        }

        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { }

        public void AddBindingParameters(
        ServiceDescription serviceDescription,
        ServiceHostBase serviceHostBase,
        Collection<ServiceEndpoint> endpoints,
        BindingParameterCollection bindingParameters)
        {
        }
    }
}

UnityInstanceProvider类:

namespace Amir.CodingChallenge.WcfService.Unity
{
    public class UnityInstanceProvider : IInstanceProvider
    {
        public UnityContainer Container { set; get; }
        public Type ServiceType { set; get; }

        public UnityInstanceProvider()
            : this(null)
        {
        }

        public UnityInstanceProvider(Type type)
        {
            ServiceType = type;
            Container = new UnityContainer();
        }

        #region IInstanceProvider Members

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

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

        #endregion
    }
}

2 个答案:

答案 0 :(得分:2)

确保您链接到服务标记中的UnityServiceHostFactory

<%@ ServiceHost 
    Language="C#" Debug="true" 
    Service="WcfServiceApplication.Implementation.ProductService" 
    Factory="WcfServiceApplication.DependencyInjection.WCF.UnityServiceHostFactory"
%>

找到标记代码对我来说是个问题。右键单击Svc并单击“查看标记” 然后,您可以将UnityServiceHostFactory添加为Factory值

How to Edit Markup

Link to Source of Answer

答案 1 :(得分:0)

确保构建正在将项目dll复制到正确的位置。 在我的情况下,我正在复制&#39; bin \ debug&#39;而正确的将是&#39; bin \&#39;