代码之家  ›  专栏  ›  技术社区  ›  James Kolpack

使用StructureMap注入工厂方法

  •  4
  • James Kolpack  · 技术社区  · 14 年前

    我用的是 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");
        }
    }
    

    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 回复  |  直到 11 年前
        1
  •  17
  •   James Kolpack    14 年前

    如果我看了超载的使用,我会发现

    Use(Func<IContext> func);
    

    …我可以用它来:

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