Нужна помощь в получении Ninject-эквивалента для синтаксиса StructureMap - PullRequest
4 голосов
/ 06 апреля 2011

Я пытаюсь реализовать IoC (Ninject) для Ravendb и столкнулся с небольшим затруднением.Я использую код http://www.dotnetguy.co.uk/post/2010/06/12/raven-db-ndash-part-1-ndash-documentsession-per-request-with-structuremap, чтобы помочь.

public interface IRavenSessionFactoryBuilder
{
    IRavenSessionFactory GetSessionFactory();
}

public class RavenSessionFactoryBuilder : IRavenSessionFactoryBuilder
{
    private IRavenSessionFactory _ravenSessionFactory;

    public IRavenSessionFactory GetSessionFactory()
    {
        return _ravenSessionFactory ?? (_ravenSessionFactory = CreateSessionFactory());
    }

    private static IRavenSessionFactory CreateSessionFactory()
    {
        Debug.Write("IRavenSessionFactory Created");
        return new RavenSessionFactory(new DocumentStore
                                           {
                                               Url =
                                                   System.Web.Configuration.WebConfigurationManager.AppSettings[
                                                       "Raven.DocumentStore"]
                                           });
    }
}

public interface IRavenSessionFactory
{
    IDocumentSession CreateSession();
}

public class RavenSessionFactory : IRavenSessionFactory
{
    private readonly IDocumentStore _documentStore;

    public RavenSessionFactory(IDocumentStore documentStore)
    {
        if (_documentStore != null) return;
        _documentStore = documentStore;
        _documentStore.Initialize();
    }

    public IDocumentSession CreateSession()
    {
        Debug.Write("IDocumentSession Created");
        return _documentStore.OpenSession();
    }
}

Я не уверен, как преобразовать следующий синтаксис структурной карты.

ObjectFactory.Configure(x => x.For<IDocumentSession>()
                  .HybridHttpOrThreadLocalScoped()
                  .AddInstances(inst => inst.ConstructedBy
                    (context => context.GetInstance<IRavenSessionFactoryBuilder>()
                      .GetSessionFactory().CreateSession())));

В моей попытке _ravenSessionFactorynull при каждом запросе из-за нового конструктора.

Bind<IDocumentSession>().ToMethod(
            x => new RavenSessionFactoryBuilder().GetSessionFactory().CreateSession()).RequestScope();

Спасибо всем, кто нашел время, чтобы попытаться помочь и объяснить.

Ответы [ 4 ]

13 голосов
/ 07 апреля 2011

Фабрики называются провайдерами в Ninject. Преобразовать SessionFactory в SessionProvider: -

public class RavenSessionProvider : Provider<IDocumentSession>
{
    private readonly IDocumentStore _documentStore;

    public RavenSessionFactory(IDocumentStore documentStore)
    {
        _documentStore = documentStore;
    }

    public IDocumentSession GetInstance(IContext ctx)
    {
        Debug.Write("IDocumentSession Created");
        return _documentStore.OpenSession();
    }
}

Также измените ваш RavenSessionFactoryBuilder на DocumentStoreProvider: -

public class DocumentStoreProvider : Provider<IDocumentStore>
{
    public IDocumentStore GetInstance(IContext ctx)
    {
        var store = new DocumentStore 
                   { Url = System.Web.Configuration.WebConfigurationManager.AppSettings["Raven.DocumentStore"]});
        store.Initialize();
        return store;
    }
}

И добавить привязки:

Bind<RavenSessionProvider>().ToSelf().InSingletonScope()
Bind<IDocumentSession>().ToProvider<RavenSessionProvider>();
1 голос
/ 06 апреля 2011

Вместо new RavenSessionFactoryBuilder().GetSessionFactory()...., я думаю, вы захотите:

Kernel.Get<IRavenSessionFactoryBuilder>().GetSessionFactory()....

, где вы сделали что-то подобное заранее:

Bind<IRavenSessionFactoryBuilder>().To<IRavenSessionFactoryBuilder>()
  .InSingletonScope();

Отказ от ответственности: Я имеюникогда не пробовал Get в Bind выражении раньше.Вам может понадобиться заводской метод.

0 голосов
/ 16 апреля 2012

Вам не нужно создавать фабрику или поставщика и т. Д., Чтобы сделать это.

Ninject выполняет сеанс для каждого запроса, поскольку вы создаете модуль Ninject, который связывает хранилище документов в InSingletonScope (), затем связывает DocumentSession в области запроса и вы готовы к работе.

Я написал пошаговое руководство для Ninject и RavenDB

http://www.dalsoft.co.uk/blog/index.php/2012/04/12/mvc-get-ravendb-up-and-running-in-5-minutes-using-ninject/

0 голосов
/ 06 апреля 2011

Ninject в основном имеет 5 опций для области действия.

TransientScope - тот, который вы используете, означает, что для каждого запроса создается новый экземпляр

SingletonScope - создается только один экземпляр

ThreadScope - для каждого потока создается только один экземпляр

RequestScope - для HttpRequest создается только один экземпляр

Пользовательский - вы предоставляете объект области действия

Если вы создаете веб-приложение, вы можете просто указать .InRequestScope() Если это приложение для Windows, вы можете указать .InThreadScope()

Наконец, если вам нужно указать гибрид (я не совсем уверен, как он работает на карте структуры), вы могли бы сделать .InScope(ctx => HttpRequest.Current != null ? HttpRequest.Current : Thread.CurrentThread)

...