我已经实现了一个可以正常工作的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
}
}
答案 0 :(得分:2)
确保您链接到服务标记中的UnityServiceHostFactory
<%@ ServiceHost
Language="C#" Debug="true"
Service="WcfServiceApplication.Implementation.ProductService"
Factory="WcfServiceApplication.DependencyInjection.WCF.UnityServiceHostFactory"
%>
找到标记代码对我来说是个问题。右键单击Svc并单击“查看标记” 然后,您可以将UnityServiceHostFactory添加为Factory值
答案 1 :(得分:0)
确保构建正在将项目dll复制到正确的位置。 在我的情况下,我正在复制&#39; bin \ debug&#39;而正确的将是&#39; bin \&#39;