Используете Ninject в приложении .NET RESTful?

Я новичок в службах 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, а те, которые мне удалось найти, просто слишком приспособлены для тех, кто знаком с постоянными посетителями с Ninject или IoC.

Кроме того, в моих уровнях «Бизнес» и «Данные» (с использованием структуры сущностей) я также ищу возможность реализовать там Ninject, лучше ли подключать слои по отдельности или все это можно сделать в одном месте?

Спасибо.

ОБНОВЛЕНИЕ 1. Я устранил проблему с привязкой, но это все еще меня не устраивает. Я использую Ninject.Extensions.Wcf, и он бомбит, ища файл NinjectWcfApplication.cs, который вообще не кажется правильным. Я использовал NuGet для включения пакета для Ninject, может ли это быть проблема с версией?


person bryan    schedule 05.12.2011    source источник
comment
Бит контекста, но я бы не советовал использовать WCF REST для вашего REST API. Этот проект мертв.   -  person Daniel Marbach    schedule 09.01.2013


Ответы (3)


Возможно, это опечатка, но вы хотите привязать интерфейсы к себе в модуле? Обычно вы привязываете интерфейс к конкретному типу. Если Ninject попытается создать экземпляр типа интерфейса, он определенно потерпит неудачу, и в зависимости от конкретного поведения обработки ошибок вашей настройки Ninject он либо выбросит, либо вернет null. Итак, убедитесь, что модуль настроен на поиск реального класса:

public class RestServiceModel : NinjectModule
    {
        public override void Load()
        {
            Bind<ITXESIIDService>().To<TXESIIDService>();
            ...
        }
    }
person KeithS    schedule 05.12.2011
comment
Вы совершенно правы, и это было исправлено. Проблема, с которой я столкнулся сейчас, заключается в том, что я использую Ninject.Extensions.Wcf и, по-видимому, у него или у меня отсутствуют файлы. Здорово. В любом случае, спасибо за внимание к проблеме привязки, я соответствующим образом отредактирую свой пост. - person bryan; 06.12.2011

При переопределении виртуального метода всегда необходимо вызывать базовый метод. См. Application_Start().

person Remo Gloor    schedule 14.12.2011

Что касается вашего обновления: я новичок в ninject, поэтому я ничего не знаю о более старых версиях, но я полагаю, вы попробуете Сначала пример расширения Ninject. Если они сбегают, значит, это что-то другое.

person tobsen    schedule 06.12.2011