2013-06-19 53 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是不需要的。 –