使用StructureMap注入工厂方法

时间:2010-06-28 18:33:57

标签: c# .net structuremap

我正在使用wrapper for the ASP.NET Membership provider,以便我可以使用更多松散耦合的库。我想使用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 个答案:

答案 0 :(得分:15)

如果我查看了使用的重载,我会找到

Use(Func<IContext> func);

...我可以用作:

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