2009-03-18 5 views
1

Je construis une DLL avec plusieurs objets "maîtres" qui ont besoin d'accéder à l'application LINQ DataContext. La DLL servira plusieurs projets avec des dataContexts différents, donc j'ai besoin que la DLL puisse appeler l'objet qui se trouve dans l'EXE.Meilleure pratique pour DLL appelant un objet dans l'EXE

Quelle est la meilleure ou la manière élégante de le faire?

Edit: Précision
exemple de code de ce que je suis en train de faire:

'DLL 
'--- 
Public MustInherit Class MasterObject(Of T As Class) 
    Friend db As DataContext 
    Public Sub New() 
     'How do I do something like this? 
     db = New DataContextInTheExe() 
    End Sub 

    ... 

    Public MustOverride Sub Save() 
end class 

'In the Exe 
'--- 
Public Class Order 
    Inherits MasterObject(Of Order) 

    Public Overrides Sub Save() 
     ... 
     Me.db.SubmitChanges() 
    End Sub 
end class 
+0

Je vais mettre à jour re le modifier ... –

Répondre

2

La meilleure façon de le faire est pour l'exe pour passer le contexte de données à la dll, par exemple en tant qu'argument de méthode pour tout ce que fait la dll, ou en tant qu'argument de constructeur pour n'importe quelle classe (dans la DLL). Si vous avez différents types de contextes de données, le type doit être DataContext ou une sous-classe. Les méthodes d'extension (sur DataContext) sont un moyen de le faire (mais pas la seule). Sinon, dans une implémentation standard de référentiel (où dll est le référentiel), il est tout à fait possible que l'appelant (l'exe) ne connaisse même pas le contexte de données - juste l'interface ICustomerRepository (ou peu importe) que la DLL expose.


Re la modification; par cela seul, il n'aurait aucun moyen de connaître le type de contexte de données à créer. Vous pouvez éventuellement soit passer un contexte de données, ou lui dire (via des génériques) le type de contexte de données; excuser mon C#, mais:

public abstract class MasterObject<TDataContext, TEntity> 
    where TDataContext : DataContext, new() 
    where TEntity : class 
{ 
    internal TDataContext db; 
    public MasterObject() { 
     db = new TDataContext(); 
    } 
} 

Cependant, je soupçonne fortement que la voie d'injection de dépendance est plus simple - à savoir laisser l'appelant nous dire:

public abstract class MasterObject<TEntity> 
    where TEntity : class 
{ 
    internal DataContext db; 
    public MasterObject(DataContext db) { 
     this.db = db; 
    } 
} 
+0

Comment le feriez-vous en utilisant méthodes d'extension? –

+0

Voulez-vous dire avoir la méthode d'extension dans l'exe? Comment la DLL serait-elle au courant de l'extension? –

+0

Non, la méthode d'extension serait dans la DLL. Une méthode d'extension est juste un moyen sophistiqué de passer une instance dans une méthode utilitaire (partagée/statique). –

3

Utiliser l'injection de dépendance en passant le contexte de données la classe qui doit le consommer dans votre DLL, généralement à travers son constructeur.

Voici un exemple en C#:

public abstract class MasterObject<T> 
{ 
    private DataContext _dataContext; 

    public MasterObject(DataContext dataContext) 
    { 
     _dataContext = dataContext; 
    } 
} 

public class Order : MasterObject<Order> 
{ 
    public Order(DataContext dataContext) : base(dataContext) 
    { 
     // additional constructor logic 
    } 
} 
+0

Pourriez-vous me donner un exemple? –

+0

Je ne sais pas pourquoi cela a été rejeté (correctif); Je suis entièrement d'accord. –

+0

Bien que la réponse soit tout à fait correcte, j'ai choisi la réponse de Marc parce qu'elle est plus complète. Merci! –

1

Il ne sait pas encore ce que vous voulez faire, alors je vais vous indiquer quelques réponses connexes J'ai posté:

En ce qui concerne la carte de la structure, l'idée est que vous l'appelez comme:

var someMaster = StructureMap.GetInstance<SomeMasterDefinedInDll>(); 

Carte Structure instanciera et passer tout ce qui est nécessaire au constructeur SomeMasterDefinedInDll. Vous avez besoin de le configurer, donc vous lui dites d'obtenir le contexte défini dans l'exe lorsqu'un DataContext est demandé. Maintenant, en général, SomeMasterDefinedInDll est une dépendance pour quelque chose d'autre, donc vous n'avez même pas besoin de faire ce code ci-dessus (c'est un paramètre du constructeur de quelque chose d'autre), vous le faites seulement pour le haut de la hiérarchie. Vérifiez les liens, il est expliqué assez clairement là-dedans.

Mise à jour: Dans la syntaxe C#, vous:

public abstract class MasterObject<T> 
{ 
    protected MasterObject(DataContext context) 
    { 
    } 
} 
public class Order : MasterObject<Order> 
{ 
    public Order() : base(new ExeDataContext()) {} 
} 

Fondamentalement, recevoir le datacontext comme paramètre constructeur, et dans la sous-classe passer le datacontext au constructeur de base.

Mise à jour 2: Notez que le code ci-dessus était en réponse à ce que vous vouliez faire à l'origine. Si vous voulez juste faire ça, ça va marcher (pas besoin d'autre chose). Cela dit, je vous recommande de regarder dans l'injection de dépendance. Dans ce cas, le ExeDataContext sera également reçu dans le constructeur Order: public Order (contexte ExeDataContext): base (contexte) {}

+0

J'ai ajouté un exemple de code, j'espère qu'il est plus clair ce que j'essaie de faire –

+0

@Eduardo mis à jour avec - comment ajouter la syntaxe dans C#, avec un commentaire pour l'effacer ... – eglasius

+0

@Freddy: Votre échantillon le code n'utilise pas l'injection de dépendance car la dépendance est toujours créée dans la DLL et non injectée depuis l'exe. –

Questions connexes