1

我是 RESTful 服务的新手,并且有一段时间不用使用 IoC 重新连接堆栈,所以这给了我一个轻微的打击。

我有一个看起来像这样(简化)的 WCF 服务:

public interface IESIID
{
    [OperationContract]
    [WebGet(UriTemplate = "/{guid}/{id}", ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Wrapped)]
    Message LookupESIID(string guid, string id);
}

public class ESIID : BaseREST<ESI>, IESIID
{
    private readonly ITXESIIDService _bllSvc;

    public ESIID(ITXESIIDService svc)
    {
        _bllSvc = svc;
    }

    public Message LookupESIID(string guid, string id)
    {
        return GetById(guid, id);
    }

    private Message GetById(string guid, string id)
    {
        apiAuthentication = new APIKeyAuthentication();
        if (!apiAuthentication.IsValidAPIKey(guid))
            return APIError();

        //_bllSvc = new TXESIIDService(); <--- WANTING TO AVOID THIS!!!!
        var results = _bllSvc.SelectByID(id);

        return results.Count == 0 ? NoResults() : CreateMessage(results);
    }
 }

好吧,这很简单。我确实添加了一个构造函数参数,因为调用了 BLL TXESIIDService 方法。

所以现在,我已经更改了 Ninject 的全局文件,现在看起来像这样:

 public class Global : NinjectWcfApplication
{
    protected override void Application_Start(object sender, EventArgs e)
    {
        RegisterRoutes();
    }

    protected override IKernel CreateKernel()
    {
        return new StandardKernel(new RestServiceModel());
    }

    private static void RegisterRoutes()
    {
        RouteTable.Routes.Add(new ServiceRoute("ESIID", new NinjectServiceHostFactory(), typeof(ESIID)));
    }

}

并添加了我的模块:

 public class RestServiceModel : NinjectModule
    {
        public override void Load()
        {
            Bind<ITXESIIDService>().To<TXESIIDService>();
            Bind<IDoNotSolicitService>().To<DoNotSolicitService>();
        }
    }

为了排除故障,我添加了自己的 NinjectServiceHostFactory

 public class NinjectServiceHostFactory : WebServiceHostFactory 
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        var serviceTypeParameter = new ConstructorArgument("serviceType", serviceType);
        var baseAddressesParameter = new ConstructorArgument("baseAddresses", baseAddresses);
        return KernelContainer.Kernel.Get<NinjectServiceHost>(serviceTypeParameter, baseAddressesParameter);
    }
}

当我像这样运行它时,我收到一条错误消息:

return KernelContainer.Kernel.Get<NinjectServiceHost>(serviceTypeParameter, baseAddressesParameter);

不能为空。

显然我在这里遗漏了一些东西,但我不知道是什么。在这一点上,我已经尝试了各种方法,我看到的大多数示例都是针对 WCF 服务的,而我设法找到的 RESTful 服务对于那些熟悉的 w/Ninject 或 IoC 常客来说有点太适合了。

此外,在我的业务和数据层(使用实体框架)中,我也希望在那里实现 Ninject,最好的做法是将这些层单独连接起来还是可以在一个地方完成所有操作?

谢谢。

更新 1 我已经更正了绑定问题,但这仍然对我造成轰炸。我正在使用 Ninject.Extensions.Wcf 并且它正在寻找 NinjectWcfApplication.cs 文件,这似乎根本不正确。我使用 NuGet 为 Ninject 包含一个包,这可能是版本问题吗?

4

3 回答 3

2

This may be a typo, but are you meaning to bind interfaces to themselves in your module? Usually you bind an interface to a concrete type. If Ninject tries to instantiate an interface type, it will definitely fail, and depending on specific error-handling behavior of your Ninject setup it'll either throw out or return null. So, make sure the module is configured to look for a real class:

public class RestServiceModel : NinjectModule
    {
        public override void Load()
        {
            Bind<ITXESIIDService>().To<TXESIIDService>();
            ...
        }
    }
于 2011-12-05T21:05:44.507 回答
2

覆盖虚拟方法时,您始终必须调用基本方法。见Application_Start()

于 2011-12-14T17:37:43.750 回答
0

关于您的更新:我是 ninject 的新手,所以我对旧版本一无所知,但我想您先试用Example Ninject Extensions。如果他们跑了,你知道它一定是别的东西。

于 2011-12-06T19:01:00.973 回答