2008-11-08 10 views
1

Je suis novice en matière d'injection de dépendance. Je me demande comment vous pourriez gérer le scénario suivant. Nous avons quelque chose comme ce qui suit:Comment injecter une dépendance changeante

public class DatabaseContext 
{ 
    public string ConnectionString {get;} 
} 

public interface IDataAccess 
{ 
    string GetString(int id); 
} 

public class DataAccessImpl : IDataAccess 
{ 
    private DatabaseContext _context; 
    public DataAccessImpl(DatabaseContext context) 
    { 
    this._context=context; 
    } 

    public string GetString(int id) 
    { 
    return "some data"; 
    } 
} 

Pour les applications Web chaque demande pourrait constituer un autre DatabaseContext pour pointer vers une autre base de données. Pour les formulaires Windows, nous pouvons modifier le DatabaseContext actuel. Comment un di framework gère-t-il une dépendance qui peut changer? De telle sorte que lorsque je demande un IDataAccess, il a toujours le DatabaseContext approprié/actuel.

+0

BTW: IMO, IDataAccess est un nom terrible pour une interface. Essayez d'utiliser un nom qui décrit son comportement. –

+0

Bien sûr, ce n'était qu'un exemple. – Kyle

Répondre

1

L'approche que j'ai prise n'est pas d'injecter un DataContext mais une fabrique DataContext, une classe avec une méthode qui renvoie un DataContext du type approprié. J'ai deux constructeurs pour, dans mon cas, une classe de contrôleur le constructeur par défaut et celui qui prend l'usine (et d'autres objets injectés). Le constructeur par défaut appelle simplement le constructeur avec des paramètres avec tous les paramètres null. Le constructeur paramétré crée des objets de types par défaut si le paramètre correspondant est null. L'utilisation de la fabrique permet à mes actions de contrôleur de créer un nouveau DataContext lorsqu'il est appelé au lieu d'avoir un seul DataContext qui existe tout au long de la vie de l'application. L'usine pourrait être construite pour retourner un contexte existant si disponible et en créer un nouveau au besoin, mais je préfère les affecter à une unité de travail.

P.S. L'usine produit en fait une classe wrapper autour d'un DataContext, pas le DataContext réel, en tant qu'interface (IDataContextWrapper). Cela rend beaucoup plus facile de se moquer de la base de données réelle de mes tests de contrôleur. Tout ce qui précède suppose LINQ/ASP.NET MVC, mais les principes sont généralement applicables, je pense.