WCF / Ninject / Default(无参数)构造函数

时间:2013-06-19 14:13:11

标签: c# wcf ninject ninject-extensions

我正在尝试使用WCF Ninject扩展将Ninject添加到WCF服务。

我收到了错误:

  

提供的服务类型无法作为服务加载,因为它没有默认(无参数)构造函数。要解决此问题,请在类型中添加默认构造函数,或将类型的实例传递给主机。

该服务具有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始终为null。

我错过了什么?

3 个答案:

答案 0 :(得分:1)

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

否则,这应该工作正常。你似乎没有使用任何拦截器,所以我可以问这个目的是什么?:

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

我假设你在这里使用某种自定义服务主机,但它不应该是你想要做的事情所必需的。让上述代码正常工作所需要的只是:

1:服务标记中的Factory属性(你有这个) 2:内核中的构造函数依赖项(你有这个)

我现在正在使用这个确切的设置,因此我认为NinjectServiceHost中的某些内容会导致此问题并尝试附加某种类型的拦截器。

答案 1 :(得分:1)

好的,我认为应该这样做。您的Ninject设置可能已关闭。我之前已经发生过这种情况,因为设置它有几种“方法”,但有些方法并不总是有效。

我看到你正在使用AspNet兼容模式并通过Web项目托管它。你正在使用Ninject.Web,对吗?实际上,您不需要从Ninject获得全局继承。从Global中删除所有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工作所需的全部内容。尝试沿着这条路走;我有预感它会解决它。

答案 2 :(得分:0)

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

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