【问题标题】:Ninject dependency for wcf errorwcf 错误的 Ninject 依赖项
【发布时间】:2015-05-02 17:02:28
【问题描述】:

我在 Asp.Net MVC 项目中使用 Ninject 已经有一段时间了,而且工作起来非常有魅力。但是现在,当我想通过安装 Ninject.Extensions.WcfNinject.Web.Common 而不是 Ninject.MVC3 将其与 WCF 服务库一起使用时,添加服务引用时出现以下错误。

System.InvalidOperationException: 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.
at System.ServiceModel.Dispatcher.InstanceBehavior..ctor(DispatchRuntime dispatch, ImmutableDispatchRuntime immutableRuntime)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime..ctor(DispatchRuntime dispatch)
at System.ServiceModel.Dispatcher.DispatchRuntime.GetRuntimeCore()
at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpened()
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)

这是我的 WCF 类构造函数 -

    private TestDBContext _dbContext;

    public TestService(TestDBContext ctx)
    {
        _dbContext = ctx;
    }

这是我在 NinjectWebCommon 中添加依赖项的方法 -

kernel.Bind<TestDBContext>().To<TestDBContext>().InRequestScope();

这里还需要什么?如何解决?

谢谢

编辑:整个 NinjectWebCommon

    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        bootstrapper.Initialize(CreateKernel);
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop()
    {
        bootstrapper.ShutDown();
    }

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        try
        {
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            RegisterServices(kernel);
            return kernel;
        }
        catch
        {
            kernel.Dispose();
            throw;
        }
    }

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

App.config

https://gist.github.com/anonymous/ad0da985773c145f2b30

【问题讨论】:

  • 这看起来很简单,但仍然没有描述 WCF 服务是如何引导的,例如 *.svc 文件和/或 web.config。
  • 它是一个 wcf 库,所以不包含 .svc。它是使用 App.config 引导的。让我知道您的调试需要其中的哪一部分。
  • 好。你能把 app.config 添加到这里吗?我认为这是工厂的问题。
  • 这对github.com/ninject/Ninject.Extensions.Wcf/wiki/…有什么帮助吗?想要在跳转之前确认。
  • 添加这个,我最好的猜测是它应该可以工作。我将更新我的答案以澄清一下。

标签: c# asp.net-mvc wcf ninject ninject-extensions


【解决方案1】:

异常是由于 Ninject 没有被正确引导。当 WCF 引导找不到无参数构造函数时,它会抛出此异常。

尝试从您的TestService 中删除参数TestDBContext ctx,看看它是否会起作用,就像测试一样。

要解决此问题,您应该确保确实为 WCF 正确设置了 Ninject。 将以下内容添加到您的 web.config

<serviceHostingEnvironment>
    <serviceActivations>
        <add factory="YourNamespace.NinjectFileLessServiceHostFactory" service="YourNamespace.TestService" relativeAddress="./TestService.svc"/>
    </serviceActivations>
</serviceHostingEnvironment>

同时创建工厂:

public class NinjectFileLessServiceHostFactory : NinjectServiceHostFactory
{
    public NinjectFileLessServiceHostFactory()
    {
        SetKernel(NinjectWebCommon.Bootstrapper.Kernel);
    }
}

要使 Bootstrapper 在此处可用,您应该在 NinjectWebCommon 中将其更改为公共访问。另外记得在 RegisterServices 中添加所需的绑定:

public static class NinjectWebCommon
{
     public static readonly Bootstrapper bootstrapper = new Bootstrapper();

     // ...

     private static void RegisterServices(IKernel kernel)
     {
         kernel.Bind<ServiceHost>().To<NinjectServiceHost>();
         // ...
      }
 }

【讨论】:

  • 我知道如果我删除参数它会起作用,但这不是问题。我正在寻找使用 wcf 库中的 dbcontext,所以接近 Ninject 方式。
  • 对不起,我想你误解了我的意思。我并不是建议将其作为解决方案删除,而只是为了测试它是否有效。因为它在没有它的情况下工作,所以确认问题确实是 WCF 没有使用 Ninject 来创建服务。
  • 是的,去掉参数后就可以了。我之前测试过。
  • 好的,太好了。为了找到 Ninject 未正确加载的解决方案,我认为您扩展了问题中设置的描述。就像不通过 .svc 文件设置服务的方式以及引导代码的外观一样。
  • 我已经粘贴了用于引导的 ninjectwebcommon 文件。
猜你喜欢
  • 1970-01-01
  • 2014-05-26
  • 2011-12-26
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 2023-03-03
  • 2011-04-06
  • 1970-01-01
相关资源
最近更新 更多