【问题标题】:Using Ninject in .NET RESTful application?在 .NET RESTful 应用程序中使用 Ninject?
【发布时间】:2011-12-05 19:52:01
【问题描述】:

我是 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 添加了一个包,这可能是版本问题吗?

【问题讨论】:

  • Bitout 上下文但我不建议将 WCF REST 用于您的 REST API。那个项目已经死了。

标签: c# ninject ioc-container ninject-extensions


【解决方案1】:

这可能是一个错字,但你的意思是在你的模块中将接口绑定到它们自己吗?通常,您将接口绑定到具体类型。如果 Ninject 尝试实例化一个接口类型,它肯定会失败,并且根据你的 Ninject 设置的特定错误处理行为,它会抛出或返回 null。因此,请确保将模块配置为查找真正的类:

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

【讨论】:

  • 您说的完全正确,并且已更正。我现在遇到的问题是我正在使用 Ninject.Extensions.Wcf 显然它或者我缺少文件。伟大的。无论如何,感谢您对绑定问题的提醒,我将相应地编辑我的帖子。
【解决方案2】:

在重写虚方法时,您总是必须调用基方法。见Application_Start()

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-26
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多