2016-07-05 3 views
1

I eine DLL mit der folgenden Hierarchie haben:Wie dynamisch eine Liste basierend Typ abgeleiteten Typ gegossen

Interface ISchema {} 

class Schema:ISchema{} 

class TableSchema:Schema{} 

class ViewSchema:Schema{} 

Ich habe eine weitere dll folgende Hierarchie aufweist:

Interface ISearch {} 

class Table:ISearch{} 

class View:ISearch{} 

Der folgende Code löst den Suchvorgang in Tabelle oder Ansicht gemäß Benutzerauswahl aus:

private void FindNowButton_Click(object sender, EventArgs e) 
{ 
    // return Table or View according to user selection. (Property is an internal class helping to retrieve the selected type) 
    var type = (ObjectsTypeComboBox.SelectedItem as Property).Type; 

    // Create an instance of table or View as ISearch 
    var instance = (ISearch)Activator.CreateInstance(type); 

    // Call to relevant Search (table.Search or View.Search) 
    // _dataManager help to get the records from Schema hierarchy 
    // text is the text to search 
    var result = instance.Search(_dataManager, FindWhatTextBox.Text); 

    // Show in DataGridView the result 
    FindResultsDGV.DataSource = result; 
} 

Jede Suchmethode Gibt eine Liste zurück. Ich muss verschiedene Spalten im Raster anzeigen. TableSchema und ViewSchema haben unterschiedliche Eigenschaften, Casting wie folgt funktioniert.

FindResultsDGV.DataSource = result.Cast<TableSchema> ; // or result.Cast<ViewSchema> 

Wie kann ich dynamisch den richtigen Typ in diesem Stadium erhalten?

Jede andere Lösung ist willkommen

UPDATE:

Nach @GiladGreen

public interface ISearchSchemaFactory 
{ 
    ISearch<ISchema> GetSearch(Type schemaType); 
} 

public class Factory : ISearchSchemaFactory 
{ 
    public ISearch<ISchema> GetSearch(Type schemaType) 
    { 
     if (schemaType.Equals(typeof(Table))) 
     { 
      return new BL.AdvancedSearch.Table(); // Getting an error here 
      // Cannot implicitly convert type 'Table' to 'ISearch<ISchema>'. An explicit conversion exists (are you missing a cast?) 
     } 
     else if (schemaType.Equals(typeof(View))) 
     { 
      // TODO 
     } 

     return null; // TODO 
    } 
} 
+0

Haben Sie überlegt, Generics zu verwenden? – Aron

Antwort

1

Ich würde Ihnen vorschlagen, die ISearch wie folgt zu ändern:

Interface ISearch<out TSchema> where TSchema: ISchema 
{ 
    TSchema Search(....); 
} 

class Table : ISearch<TableSchema> 
{ 
    public TableSchema Search(....) 
    { 
     //Some searching code 
    } 
} 

class View:ISearch<ViewSchema> 
{ 
    public ViewSchema Search(....) 
    { 
     //Some searching code 
    } 
} 

Dann können Sie auch einehaben, dass Sie eine Instanz der richtigen ISearch geben wird, dass Sie die TSchema nach müssen Sie geben ihm:

public interface ISearchSchemaFactory 
{ 
    ISearch<ISchema> GetSearch(Type schemaType); 
} 

Und die Nutzung: var search = factory.GetSearch(type);


Factoy Implementierung Beispiel

public class MappingSearchSchemaFactory : ISearchSchemaFactory 
{ 
    public MappingSearchSchemaFactory(Dictionary<Type, ISearch<ISchema>> mapping) 
    { 
     Mapping = mapping; 
    } 

    ISearch<ISchema> GetSearch(Type schemaType) 
    { 
     ISearch<ISchema> result; 
     if(!Mapping.TryGetValue(schemaType, out result) 
     { 
      //Some logging or throwing exception behavior - depends what you want 
     } 
     return result; 
    } 
    public Dictionary<Type, ISearch<ISchema>> Mapping { get; set; } 
} 

Diese spezifische Implementierung wird für "einige ein "das Mapping. Ein möglicher Initialisierungscode kann sein:

ISearchSchemaFactory factory = new MappingSearchSchemaFactory(
    new Dictionary<Type,ISearch<ISchema>> 
    { new TableSchema(), new Table() }, 
    { new ViewSchema(), new view() } 
); 

Aber ich würde das weniger empfehlen. Ich würde Dependency Injection und IoC Containers betrachten, um die Initialisierung meiner Objekte zu verwalten. Ich persönlich benutze Castle Windsor

+1

müssen Sie GetSearch-Methode wie GetSearch () oder GetSearch aufrufen, so dass das Problem weiterhin besteht. –

+0

Wahr. Bearbeitete die Methode der Fabrik. –

+0

jetzt Ihre Methode ist nicht generisch so 'ISearch GetSearch (Typ schemaType);' wird nicht kompilieren. –

Verwandte Themen