Внедрение фабричного метода с использованием StructureMap - PullRequest
4 голосов
/ 28 июня 2010

Я использую оболочку для поставщика членства ASP.NET , чтобы можно было более свободно использовать библиотеку. Я хочу использовать StructureMap для обеспечения истинного IoC, но у меня возникают проблемы с его настройкой с помощью объекта фабрики User-to-Profile, который я использую для создания экземпляра профиля в контексте пользователя. Вот соответствующие детали, сначала интерфейс и обертка из библиотеки:

// From ASP.Net MVC Membership Starter Kit
public interface IProfileService
{
    object this[string propertyName] { get; set; }
    void SetPropertyValue(string propertyName, object propertyValue);
    object GetPropertyValue(string propertyName);
    void Save();
}

public class AspNetProfileBaseWrapper : IProfileService
{
    public AspNetProfileBaseWrapper(string email) {}

    // ...
}

Далее, хранилище для взаимодействия с конкретным свойством в данных профиля:

class UserDataRepository : IUserDataRepository
{
    Func<MembershipUser, IProfileService> _profileServiceFactory;

    // takes the factory as a ctor param 
            // to configure it to the context of the given user
    public UserDataRepository(
              Func<MembershipUser, IProfileService> profileServiceFactory)
    {
        _profileServiceFactory = profileServiceFactory;
    }

    public object GetUserData(MembershipUser user)
    {
        // profile is used in context of a user like so:
        var profile = _profileServiceFactory(user);
        return profile.GetPropertyValue("UserData");
    }
}

Вот моя первая попытка предоставить конфигурацию реестра StructureMap, но она явно не работает:

public class ProfileRegistry : Registry
{
    public ProfileRegistry()
    {
        // doesn't work, still wants MembershipUser and a default ctor for AspNetProfileBaseWrapper
        For<IProfileService>().Use<AspNetProfileBaseWrapper>();
    }
}

Теоретически, как бы я хотел зарегистрироваться, это выглядело бы примерно так:

// syntax failure :)
For<Func<MembershipUser, IProfileService>>()
  .Use<u => new AspNetProfileBaseWrapper(u.Email)>();

... где я могу определить заводской объект в конфигурации. Это явно недопустимый синтаксис. Есть ли простой способ сделать это? Должен ли я использовать какой-то другой шаблон, чтобы разрешить создание моего UserDataRepository в контексте пользователя? Спасибо!

1 Ответ

15 голосов
/ 29 июня 2010

Если бы я посмотрел на перегрузки для использования, я бы нашел

Use(Func<IContext> func);

..., который я могу использовать как:

For<IUserService>().Use(s =>
   new AspNetMembershipProviderWrapper(Membership.Provider));
...