2013-06-19 52 views
4

我想添加Ninject到使用WCF Ninject扩展的WCF服务。WCF/Ninject /默认(无参数)构造函数

,我发现了错误:

The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.

服务有Ninject服务主机工厂:

<%@ ServiceHost Language="C#" Debug="true" CodeBehind="SchedulingSvc.svc.cs" 
      Service="Scheduling.SchedulingSvc" 
      Factory="Ninject.Extensions.Wcf.NinjectWebServiceHostFactory" %> 

Global.asax文件从NinjectHttpApplication继承和CreateKernel返回一个新内核NinjectModule:

public class Global : NinjectHttpApplication 
{ 
    protected override IKernel CreateKernel() 
    { 
     return new StandardKernel(new NinjectServiceModule()); 
    } 
} 

的NinjectModule:

public class NinjectServiceModule : NinjectModule 
{ 
    public override void Load() 
    { 
     this.Bind<ISchedulingService>().To<SchedulingSvc>(); 
     this.Bind<ISchedulingBusiness>().To<SchedulingBusiness>(); 
    } 
} 

与构造器注入的服务:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
public class SchedulingSvc : ISchedulingService 
{ 
    private ISchedulingBusiness _SchedulingBusiness = null; 

    public SchedulingSvc(ISchedulingBusiness business) 
    { 
     _SchedulingBusiness = business; 
    } 

    public CalendarEvent[] GetCalendarEvents() 
    { 
     var calendarEvents = _SchedulingBusiness.GetCalendarEvents(); 
     return calendarEvents; 
    } 
    ... 
} 

财产注射服务:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
public class SchedulingSvc : ISchedulingService 
{ 
    [Inject] public ISchedulingBusiness _SchedulingBusiness { get; set; } 

    public SchedulingSvc() 
    { 
    } 

    public CalendarEvent[] GetCalendarEvents() 
    { 
     var calendarEvents = _SchedulingBusiness.GetCalendarEvents(); 
     return calendarEvents; 
    } 
    ... 
} 

如果我使用构造函数注入,我会在后顶部提到的错误。如果我尝试使用属性注入,_ScheduleBusiness始终为空。

我错过了什么?

+0

您是否注册过'SchedulingBusiness'的所有必需的依赖关系? – mipe34

+0

@ mipe34是的。当我将业务插入Ninject的控制台应用程序时,所有工作都按预期进行。 –

回答

0

我想WCF(或任何网络)服务需要一个参数少的构造函数来实例化一个服务。由于您提供了参数化构造函数,因此Ninject可能无法初始化您的服务。

请注意。参考此链接以及 http://social.msdn.microsoft.com/Forums/vstudio/en-US/550d82eb-a2bc-4c08-b846-e3fb1b966457/no-parameterless-constructor-error-in-wcf

+0

如果你有一个服务的InstanceProvider,我不认为这是真的。我正在看的一件事是Ninject/WCF的一个例子,在这里http://www.aaronstannard.com/post/2011/08/16/dependency-injection-ninject-wcf-service.aspx。他的例子没有无参数的构造函数,示例代码也可以工作。但我的代码没有。 –

+0

是的,你是对的。但是WCF提供的默认InstanceProvider查找服务的无参数构造函数。我会看到你给出的链接。 – vibhu

1

我遇到错误消息尝试时是使用一个拦截器的唯一时间(通过使用Ninject.Extensions.Interceptor库和/或城堡DynamicProxy)。这是没有按部分不喜欢带参数的构造函数。

否则,这应该工作正常。它似乎并不像你使用任何拦截,所以我会问这个是什么目的?:

this.Bind<ServiceHost>().To<NinjectServiceHost>(); 

我假设你正在使用某种形式的定制服务主机的位置,但它不该”对你想要做的事情来说是必要的。所有你需要得到你上面的代码工作是:

1:在你的内核结合的构造函数依赖(你有这样的)

我有:在服务标记(你有这样的) 2工厂属性这个确切的设置现在正在工作,所以我认为你的NinjectServiceHost中的某些东西导致了这个问题,并尝试附加某种拦截器。

+0

另外,是否有任何特殊原因需要构造函数注入,而不是使用[Inject]属性注入属性? – ParaSwarm

+0

我已更新帖子。我将工厂更改为使用NinjectWebServiceHostFactory而不是NinjectServiceHostFactory。 (我有一个webHttpBinding端点和一个wsHttpBinding端点。)我删除了“ServiceHost”绑定并为该服务添加了一个绑定。我也尝试删除参数构造函数并使用属性注入。我在prop prop注入的尝试一直返回null。 –

+0

Moshimoshi - 尝试将该属性设置为公共范围,或修改Ninject内核设置以使用InjectNonPublic = true,如下所示: var settings = new NinjectSettings {InjectNonPublic = true}; var kernel = new StandardKernel(settings); – ParaSwarm

1

好的,我认为这应该做到这一点。您的Ninject安装程序可能关闭。之前我曾经遇到过这种情况,因为有几种“方法”可以设置,但其中一些并不总是有效。

我看到您正在使用AspNet兼容模式并通过Web项目托管此模式。你正在使用Ninject.Web,对吗?实际上,您不需要从Ninject获得全局继承。从全局删除所有Ninject引用和代码,并摆脱NinjectServiceModule。如果您从NuGet安装Ninject.Web,它应该在您的App_Start文件夹中创建了文件“NinjectWebCommon.cs”。这是您设置的绑定,就像这样:

private static IKernel CreateKernel() 
    { 
     var settings = new NinjectSettings { InjectNonPublic = true }; 

     var kernel = new StandardKernel(settings); 
     kernel.Bind<Func<IKernel>>().ToMethod(ctx =>() => new Bootstrapper().Kernel); 
     kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); 

     RegisterServices(kernel); 

     return kernel; 
    } 

    /// <summary> 
    /// Load your modules or register your services here! 
    /// </summary> 
    /// <param name="kernel">The kernel.</param> 
    private static void RegisterServices(IKernel kernel) 
    { 
     kernel.Bind<AdminHelper>().ToSelf().InRequestScope(); 
     kernel.Bind<AuditHelper>().ToSelf().InRequestScope(); 
     kernel.Bind<ErrorHelper>().ToSelf().InRequestScope(); 
     kernel.Bind<GoalHelper>().ToSelf().InRequestScope(); 
    } 

应该已经有了这些方法在那里,大部分都已经填充,所以你应该只与您的绑定来填充RegisterServices。

在您的App_Start文件夹中还应该有一个NinjectWeb.cs。你不应该改变它;只是验证它存在。

之后,您可能还需要将服务标记中的Factory属性更改回“Ninject.Extensions.Wcf.NinjectServiceHostFactory”。或者尝试一下,看看有什么作用。

这两个文件都是让Ninject正常工作所需要的。尝试沿着这条路线走下去;我有预感它会修复它。

+0

我很欣赏你为帮助我而付出的所有努力。我从来没有能够进去尝试你的最新建议。我被告知继续前进,但没有发现。依赖注入是我的想法,并不符合决策者的优先事项。 –

+0

不用担心的人。我完全理解;) – ParaSwarm

+0

这是解决方案。我有同样的问题,并修复了这个问题。您需要将Ninject.Web拉下来,而不仅仅是Ninject.Extensions.Wcf。我不知道为什么Ninject不会仅仅包含Ninject.Web作为Ninject.Extensions.Wcf的依赖项,如果可以的话,会提出请求。 Global.asax是不需要的。 –