StructureMap, Entity Framework и IRepository / IUnitOfWork Configuration - PullRequest
2 голосов
/ 15 октября 2011

Я использую StructureMap с Entity Framework и шаблонами IRepository / IUnitOfWork в приложении ASP.NET MVC.Цель состоит в том, чтобы все объекты были ограничены текущим HTTP-запросом следующим образом:

For<ObjectContext>()
    .HttpContextScoped()
        .Use<MembershipEntities>()
            .Ctor<string>("connectionString")
                .Is("name=MembershipEntities")
        .Named(MembershipObjectContextInstanceKey);

For<IObjectContext>()
    .HttpContextScoped()
        .Use<ObjectContextAdapter>()
            .Ctor<ObjectContext>("objectContext")
                .Is(c => c.GetInstance<ObjectContext>(MembershipObjectContextInstanceKey))
        .Named(MembershipIObjectContextInstanceKey);

For<IUnitOfWork>()
    .HttpContextScoped()
        .Use<UnitOfWork>()
            .Ctor<IObjectContext>("objectContext")
                .Is(x => x.GetInstance<IObjectContext>(MembershipIObjectContextInstanceKey))
        .Named(MembershipUOWInstanceKey);

For(typeof(IRepository<>))
    .HttpContextScoped()
        .Use(typeof(Repository<>))
            .CtorDependency<IObjectContext>("objectContext")
                .IsNamedInstance(MembershipIObjectContextInstanceKey)
        .Named(MembershipIRepositoryInstanceKey);

Однако, когда я запускаю этот код и получаю именованный экземпляр IRepository и IUnitOfWork, их внутренние IObjectContextsэто не тот же экземпляр, который не является моим намерением.

Есть идеи, что я делаю неправильно?Любая помощь будет наиболее ценной!

1 Ответ

0 голосов
/ 19 октября 2011

StructureMap поддерживает две формы внедрения зависимостей:

  1. Внедрение в конструктор - «Заставить» зависимости в конкретный класс с помощью аргументов конструктора.
  2. Setter Injection - «Перетаскивание» зависимостей в конкретный класс через открытые свойства. Номенклатура "Сеттер" взята из Java, где свойствами являются getSomething () и setSomething (value).

Я добился отличных результатов, используя конфигурацию, подобную следующей:

// In my projects, I have something like a DataContext (IDataContext's implementation) expose my ObjectContext...
// * You don't need to HttpContextScope everything, usually the ObjectContext is sufficient
For<ObjectContext>()
    .HttpContextScoped()
    .Use<MembershipEntities>()
    .Ctor<string>("connectionString")
    .Is("name=MembershipEntities")
    .Named(MembershipObjectContextInstanceKey);

// Usually, I don't abstract or wrap the ObjectContext, it is simply injected, under the hood
// ObjectContextAdapter receives an ObjectContext (HttpContextScoped)
For<IObjectContext>().Use<ObjectContextAdapter>();

// Ctor receives a IObjectContext
// * Again, if you have absolutely no use for IObjectContext, it shouldn't exist and UnitOfWork's ctor should receive the HttpContextScoped ObjectContext
For<IUnitOfWork>().Use<UnitOfWork>();

// Ctor receives a IObjectContext [...]
For(typeof(IRepository<>)).Use(typeof(Repository<>));

Это более или менее так, как я это делаю, каждый раз.

Дайте мне знать, если это работает для вас. С уважением, Max

...