2010-12-03 35 views
6

Voici ce que j'ai maintenantUnity Application Block, Comment passer un paramètre à Injection Factory?

Container.RegisterType<IUserManager, UserManagerMock>(); 
    Container.RegisterType<IUser, UserMock>(
       new InjectionFactory(
        (c) => c.Resolve<IUserManager>().GetUser("John"))); 

et l'obtenir

Container.Resolve<IProfile>(); 

Je veux passer un nom comme paramètre usine pour que je serai en mesure de résoudre l'objet utilisateur avec le nom; Quelque chose comme ceci:

Container.Resolve<IProfile>("Jonh"); 

Comment puis-je modifier l'enregistrement de type pour ce cas?

+0

Personnellement, je ne tenterais pas de récupérer un IUser/IProfile via l'emplacement du service. Il est correct de simplement récupérer l'IUserManager via l'emplacement du service, puis d'appeler GetUser ("John") dans votre code. –

+0

Je suis d'accord avec John. Si possible, essayez d'utiliser l'injection de dépendance au lieu de l'emplacement du service. Cela vous permet de garder votre code exempt d'appels vers le conteneur et d'avoir un seul (ou tout au plus quelques) emplacement (s) dans votre application qui appelle le conteneur. – Steven

Répondre

7

Alors que la plupart des cadres de DI ont des fonctionnalités avancées pour faire ces types d'enregistrements, je change personnellement plutôt la conception de mon application pour résoudre un tel problème. Cela maintient ma configuration DI simple et rend le code plus facile à comprendre. Spécialement pour la création d'objets qui dépendent d'un contexte (thread, requête, peu importe) ou dont la vie doit être gérée explicitement, j'aime définir des usines. Les usines rendent ces choses beaucoup plus explicites.

Dans votre situation, vous souhaitez récupérer un profil pour un utilisateur donné. C'est typiquement quelque chose que vous voudriez avoir une usine pour. Voici un exemple de ceci:

// Definition 
public interface IProfileFactory 
{ 
    IProfile CreateProfileForUser(string username); 
} 

// Usage 
var profile = Container.Resolve<IProfileFactory>() 
    .CreateProfileForUser("John"); 

// Registration 
Container.RegisterType<IProfileFactory, ProfileFactory>(); 

// Mock implementation 
public class ProfileFactory : IProfileFactory 
{ 
    public IProfile CreateProfileForUser(string username) 
    { 
     IUser user = Container.Resolve<IUserManager>() 
      .GetUser(username); 

     return new UserProfile(user); 
    } 
} 

J'espère que cela aide.

+0

Je pense que ce qui me dérange à propos d'exemples comme celui-ci (si nous appelons le conteneur) est que vous appelez le conteneur directement. Tout n'est pas à propos de ça, je ne vais pas citer le proverbe douteux mais vous savez ce que je veux dire ... – brumScouse

+0

Désolé mon pote, je viens de voir le commentaire ci-dessus ... – brumScouse

+0

Steven .. très apprécié, simple, gentil , efficace .. cela fonctionne comme un charme pour moi – alhpe

6

La méthode de résolution permet de transmettre les paramètres de ResolverOverride. Sous-type de ResolverOverride est ParameterOverride qui peut être utilisé pour passer le paramètre au constructeur résolu.

Vous pouvez le faire de cette façon (paramètre est le nom et la valeur passée est John):

Container.Resolve<IProfile>(new ParameterOverride("Name", "John")); 
+0

Vrai, mais vous n'obtiendrez pas ces paramètres passés dans la méthode d'usine – haim770