未调用WCF自定义服务主机工厂
我已经实现了一个WCF服务库(.NET4.5),它运行良好。 然后,我尝试使用定制的服务主机工厂实现Unity DI。调试应用程序我注意到工厂中的CreateServiceHost方法没有被调用,因此我的服务构造函数(使用依赖项作为参数)没有被调用,我得到以下错误: System.InvalidOperationException:无法将提供的服务类型作为服务加载,因为它没有默认(无参数)构造函数。若要解决此问题,请向该类型添加默认构造函数,或将该类型的实例传递给主机 我的自定义服务主机工厂:未调用WCF自定义服务主机工厂,wcf,dependency-injection,.net-4.5,Wcf,Dependency Injection,.net 4.5,我已经实现了一个WCF服务库(.NET4.5),它运行良好。 然后,我尝试使用定制的服务主机工厂实现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>
确保在服务标记中链接到UnityServiceHostFactory
<%@ ServiceHost
Language="C#" Debug="true"
Service="WcfServiceApplication.Implementation.ProductService"
Factory="WcfServiceApplication.DependencyInjection.WCF.UnityServiceHostFactory"
%>
找到标记代码是我的问题。只需右键单击Svc并单击“查看标记”
然后,您可以将UnityServiceHostFactory添加为工厂值
确保生成正在将项目dll复制到正确的位置。
在我的例子中,我复制的是“bin\debug”,正确的是“bin\”。请向我们展示您的UnityServiceHost实现。类型MovieService没有在unity容器中注册吗?Jon,我已经在UnityConfig.RegisterComponents()方法中注册了IShowService,而不是IMovieService。正如我所知,Unity需要注册依赖项,而不是依赖项消费者,但是我也尝试注册IMovieService,但它没有解决问题!我更新了我的帖子以显示我的其余代码。ShowService有一个无参数构造函数吗?
relativeAddress=“./MovieService.svc”
不应该是relativeAddress=“MovieService.svc”
ShowService构造函数是无参数的吗。
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();
}
}
}
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)
{
}
}
}
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
}
}
<%@ ServiceHost
Language="C#" Debug="true"
Service="WcfServiceApplication.Implementation.ProductService"
Factory="WcfServiceApplication.DependencyInjection.WCF.UnityServiceHostFactory"
%>