在.NET RESTful应用程序中使用Ninject

本文关键字:Ninject 应用程序 NET RESTful | 更新日期: 2023-09-27 18:16:47

我是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);

不能为null。

很明显,我错过了一些东西,但我不知道是什么。在这一点上,我尝试了各种方法,我看到的大多数例子都是针对WCF服务的,而我设法找到的RESTful服务有点太适合那些熟悉的w/Ninject或IoC常客了。

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

谢谢。

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

在.NET RESTful应用程序中使用Ninject

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

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

重写虚拟方法时,必须始终调用基方法。参见Application_Start()

关于您的更新:我是ninject的新手,所以我对旧版本一无所知,但我想您应该先尝试一下示例ninject扩展。如果他们跑了,你知道一定是别的原因。