Injecting a factory method using StructureMap
I'm using a wrapper for the ASP.NET Membership provider so that I can have more loosely coupled usage of the library. I'm wanting to use StructureMap to provide true IoC, but I'm having trouble with configuring it with a User-to-Profile factory object that I'm using to put instantiate the profile in the context of a user. Here's the relevant details, first the interface and wrapper from the library:
// 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) {}
// ...
}
Next, a repository for interacting with a particular property in the profile data:
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");
}
}
Here's my first attempt at providing a StructureMap registry config, but it obviously doesn't work:
public class ProfileRegistry : Registry
{
public ProfileRegistry()
{
// doesn't work, still wants MembershipUser and a default 开发者_如何转开发ctor for AspNetProfileBaseWrapper
For<IProfileService>().Use<AspNetProfileBaseWrapper>();
}
}
Theoretically how I'd like to register it would look something like:
// syntax failure :)
For<Func<MembershipUser, IProfileService>>()
.Use<u => new AspNetProfileBaseWrapper(u.Email)>();
...where I can define the factory object in the configuration. This is obviously not valid syntax. Is there an easy way to accomplish this? Should I be using some other pattern to allow constructing my UserDataRepository in the context of a user? Thanks!
If I had looked at the overloads for Use, I would have found
Use(Func<IContext> func);
...which I can use as:
For<IUserService>().Use(s =>
new AspNetMembershipProviderWrapper(Membership.Provider));
精彩评论