Конфигурация StructureMap для DI с комбо asp.net MVC / Linq2Sql? - PullRequest
1 голос
/ 01 марта 2012

Вот моя неполная конфигурация StructureMap:

PS: Большие извинения за то, что я прошу вас написать мое приложение для меня, но я нахожу, что API StructureMap немного сбивает с толку, поскольку почти все, что я нахожу, когда делаюПоиск в Google относится к более старому API.

    public static void Configure(IContainer container)
    {
        container.Configure(c =>
        {
            string connectionString = ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
            SQLDataContext dataContext = new SQLDataContext(connectionString);

            c.For<SQLDataContext>().HttpContextScoped();

            c.For<IAdminRepository>().Use<SQLAdminRepository_v2>().Ctor<SQLDataContext>().Is(dataContext);
            c.For<IMemberRepository>().Use<SQLMemberRepository_v2>().Ctor<SQLDataContext>().Is(dataContext);
            c.For<IUtilityRepository>().Use<SQLUtilityRepository_v2>().Ctor<SQLDataContext>().Is(dataContext);

            c.For<IAdminService>().Use<AdminService_v2>();
            c.For<IMemberService>().Use<MemberService_v2>();
            c.For<IUtilityService>().Use<UtilityService_v2>();

            c.For<ResourcePool>().Singleton();

        });
    }

Каждый сервис имеет зависимость от соответствующего репозитория, который передается через его конструктор.Например:

public class ContactService_v2 : IContactService
{
    IContactRepository contactRepository;

    public ContactService_v2(IContactRepository contactRepository)
    {
        this.contactRepository = contactRepository;
    }

    public IQueryable<Contact> Get_Contacts()
    {
        return contactRepository.GetContacts();
    }

    public void Save_Contact(Contact contact)
    {
        contactRepository.Save_Contact(contact);
    }
}

Таким образом, слой Service - это просто фасад, за которым лежит реальный репозиторий.[и прежде, чем вы спросите или предложите - нет, я не буду менять это в спешке, потому что сначала я просто хочу, чтобы DI работал, чтобы сделать код тестируемым, прежде чем я начну делать что-то драматическое.]

Q1:Приложение использует Linq2Sql для доступа к данным.Важно, чтобы все службы, отправляемые каждому контроллеру, имели в своей зависимости от репозитория зависимость от одного и того же экземпляра контекста данных, поскольку им может потребоваться объединиться друг с другом в сложных запросах, выполняемых через репозитории.Поэтому я хочу использовать жизненный цикл HttpContext для контекста данных.Это (выше), как я это делаю?

Q2: ResourcePool использовался для следования одноэлементному шаблону, но я реорганизовал его в обычный класс, принимая один сервис в качестве параметра конструктора.Это правильно?В этом случае будет ли он вести себя так, как если бы он поступил из кэша приложения asp.net?

В3. Каковы эквиваленты автоматической регистрации для конфигураций репозитория и службы?[PS: Да, я знаю, что суффикс "_v2" является нетрадиционным, но уже существуют устаревшие эквиваленты каждого XService и XRepository, которые я хочу реорганизовать на досуге после того, как DI был добавлен и работает без проблем].

Asp.Net MVC позволяет иметь сильную привязку модели следующим образом:

[HttpPost]
public ActionResult List(AdminDisplay admin)
{
    admin.GetAdminPage();
    return View(admin);
}

В таком случае каждому классу (например, AdminDisplay) требуется конструктор по умолчанию без параметров, чтобы инфраструктура MVC могла его создать.Кроме того, любой класс, созданный внутри такого класса, связанного с моделью, также нуждается в таком конструкторе без параметров.

В4: Если я хочу заменить эти конструкторы без параметров, достаточно ли просто добавить записи для них в код конфигурации StructurMap?- или мне не нужно делать это при условии, что все эти классы связывания моделей и их зависимые элементы имеют конструкторы, которые используют только те параметры, которые может разрешить StructureMap.

Извинения за неправильное форматирование, приведенное выше, но как отключитьРедактирование wysiwyg?

PS: Разрешается давать ответы на любые вопросы Q1, Q2, Q3, Q4, не отвечая на все из них!

1 Ответ

1 голос
/ 03 апреля 2012

1: Измените код для контекста данных с:

SQLDataContext dataContext = new SQLDataContext(connectionString);
c.For<SQLDataContext>().HttpContextScoped();

до:

c.For<SQLDataContext>().HybridHttpOrThreadLocalScoped()
.Use(() => new SQLDataContext(connectionString));

Измените код для каждого хранилища с:

c.For<IAdminRepository>().Use<SQLAdminRepository_v2>()
.Ctor<SQLDataContext>().Is(dataContext);

до:

c.For<IAdminRepository>().Use<SQLAdminRepository_v2>()
.Ctor<SQLDataContext>();
...