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

时间:2011-12-05 19:52:02

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

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

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

重写虚拟方法时,总是必须调用基本方法。请参阅Application_Start()

答案 2 :(得分:0)

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