2010-06-28 6 views
4

J'utilise un wrapper for the ASP.NET Membership provider afin d'avoir une utilisation de la bibliothèque plus faiblement couplée. Je souhaite utiliser StructureMap pour fournir un vrai IoC, mais j'ai du mal à le configurer avec un objet factory User-to-Profile que j'utilise pour instancier le profil dans le contexte d'un utilisateur. Voici les détails pertinents, d'abord l'interface et l'enveloppe de la bibliothèque:Injection d'une méthode d'usine à l'aide de StructureMap

// 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) {} 

    // ... 
} 

Ensuite, un référentiel pour interagir avec une propriété particulière dans les données de profil:

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"); 
    } 
} 

Voilà ma première tentative de fournir un StructureMap config de registre, mais il ne fonctionne évidemment pas:

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

Théoriquement comment je voudrais enregistrer ressemblerait à quelque chose comme:

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

... où je peux définir l'objet usine dans la configuration. Ce n'est évidemment pas une syntaxe valide. Y a-t-il un moyen facile d'accomplir cela? Dois-je utiliser un autre modèle pour autoriser la construction de UserDataRepository dans le contexte d'un utilisateur? Merci!

Répondre

15

Si je l'avais regardé les surcharges d'utilisation, je l'aurais trouvé

Use(Func<IContext> func); 

... que je peux utiliser comme:

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

+1 m'a dépanné, content d'avoir trouvé ce . –

+1

Pourquoi n'est-ce pas dans les documents officiels en haut?!? – Yojin