2013-06-19 3 views
4

WCF Ninject 확장을 사용하여 WCF 서비스에 Ninject를 추가하려고합니다.WCF/Ninject/Default (매개 변수가없는) 생성자

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

Global.asax 파일이 NinjectHttpApplication에서 상속 및 CreateKernel이있는 새로운 커널을 반환

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에 서비스 호스트 공장이 있습니다

나는 오류를 받고 있어요 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입니다.

무엇이 누락 되었습니까?

+0

'SchedulingBusiness'에 대한 모든 필수 종속성을 등록 했습니까? – mipe34

+0

@ mipe34 예. Ninject를 사용하여 비즈니스를 콘솔 앱에 연결하면 예상대로 작동합니다. –

답변

0

WCF (또는 모든 웹) 서비스는 서비스를 인스턴스화하기 위해 매개 변수가 적은 생성자가 필요하다고 생각합니다. 매개 변수화 된 생성자를 제공 했으므로 Ninject가 서비스를 초기화하지 못했을 수 있습니다.

Pls. 이 링크를 참조하는 것은 물론 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>(); 

을? : 무엇을 요청할 수 있지만, shouldn 당신이하려는 일에 꼭 필요합니다. 당신이 당신의 위의 코드 작업을 진행 할 필요가있다 :

1 : 커널에 바인딩 생성자 의존성 (이있다)

내가 가진 : 2 서비스 태그 (이있다)의 공장 속성 이 정확한 설정이 바로 지금 작동하므로 NinjectServiceHost의 일부가이 문제를 일으키고 어떤 종류의 인터셉터를 연결하려고 시도하고 있다고 생각합니다.

+0

또한 [Inject] 속성을 사용하여 속성 주입이 아닌 생성자 주입이 필요한 특별한 이유가 있습니까? – ParaSwarm

+0

게시물을 업데이트했습니다. NinjectServiceHostFactory 대신 NinjectWebServiceHostFactory를 사용하도록 Factory를 변경했습니다. (나는 webHttpBinding 끝점과 wsHttpBinding 끝 점이 있습니다.) "ServiceHost"바인딩을 제거하고 서비스에 대한 바인딩을 추가했습니다. 또한 paramater'd 생성자를 제거하고 속성 삽입을 사용하여 시도했습니다. 소품 주입에 대한 나의 시도는 계속 null을 반환합니다. –

+0

모시 모시 - 해당 속성을 공용 범위로 설정하거나 Ninject 커널 설정을 수정하여 InjectNonPublic = true를 사용하십시오 (예 : var settings = new NinjectSettings {InjectNonPublic = true}; var kernel = 새 표준 커널 (설정); – ParaSwarm

1

그래,이게 그렇게해야한다고 생각해. Ninject 설정이 꺼져있을 수 있습니다. 나는 이것을 설정하기 위해 몇 가지 "방법"이 있기 때문에 이전에 이런 일이 있었지만 그 중 일부는 항상 작동하지 않습니다.

AspNet 호환 모드를 사용하고 있으며 웹 프로젝트를 통해이 모드를 호스팅하고 있습니다. Ninject.Web을 사용하고 있습니다, 맞습니까? 실제로 Ninject에서 글로벌 상속을받을 필요는 없습니다.Global에서 모든 Ninject 참조 및 코드를 제거하고 NinjectServiceModule을 제거하십시오. NuGet에서 Ninject.Web을 설치 한 경우 App_Start 폴더에 "NinjectWebCommon.cs"파일을 생성해야합니다. 그들 중 대부분은 이미 채워 당신은 당신의 바인딩 RegisterServices을 채울 수 있어야한다, 그래서

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(); 
    } 

그것은 이미 거기에, 그 방법이 있어야합니다 당신과 같이 당신의 바인딩을 설정하는 곳이다.

또한 App_Start 폴더에 NinjectWeb.cs이 있어야합니다. 변경하지 않아도됩니다. 그것이 존재하는지 확인하십시오.

서비스 마크 업의 공장 속성을 나중에 "Ninject.Extensions.Wcf.NinjectServiceHostFactory"로 다시 변경해야 할 수도 있습니다. 또는 둘 다 시도해보고 어떤 것이 효과가 있는지보십시오.

이 두 파일은 Ninject가 작동하는 데 필요한 모든 것입니다. 이 길로 내려가보십시오. 나는 그것을 고칠 직감이있다.

+0

나를 도우려는 모든 노력에 감사드립니다. 나는 들어가서 당신의 최신 제안을 시도 할 수 없었습니다. 나는 그것을 알아 내지 않고 계속 전진해야한다고 들었다. 의존성 주입은 제 생각이었고 의사 결정권자의 우선 순위와 일치하지 않았습니다. –

+0

걱정할 필요가 없습니다. 나는 완전히 이해한다;) – ParaSwarm

+0

이것은 해결책이다. 나는 똑같은 문제가 있었는데 이것으로 해결되었다. Ninject.Extensions.Wcf뿐만 아니라 Ninject.Web을 끌어 내려야합니다. 왜 Ninject가 Ninject.Extensions.Wcf의 의존성으로 Ninject.Web을 포함하지 않는지는 알 수 없습니다. 가능한 경우 요청할 것입니다. Global.asax는 필요하지 않습니다. –

관련 문제