Hallo,
ich gaube ich habe wohl einen großen denkfehler, komme aber einfach nicht auf eine saubere lösung.
Folgendes Problem: Ich habe eine Basisklasse Repository<T>, welche in einem Presenter<T> verwendet wird.
Von diesem Repository habe ich ein spezielles abgeleitet: NewsRepository hat eine spezielle Methode zur Volltextsuche, die nur mit dem Datentyp News verwendet werden kann.
Zur Erzeugung benutze ich eine Factorymethod.
Basisklasse:
public class Repository<T> where T:class
{
//Factorymethod
public static Repository<T> Create()
{
if (typeof(T) == typeof(News))
return (Repository<News>)new NewsRepository() as Repository<T>;
return new Repository<T>();
}
//weitere Methoden
}
NewsRepository
public class NewsRepository:Repository<News>
{
public IEnumerable<News> Search(string searchTerm, IEnumerable<System.Linq.Expressions.Expression<Func<News, bool>>> filters, List<KeyValuePair<string, bool>> sorters, int maxCount, int skip, bool readOnly)
{
//suche
}
}
Und benutzung im Presenter:
public abstract class DataPresenterBase<T> : PresenterBase, IDataPresenterBase where T: class {
protected List<T> _data;
protected Repository<T> _repository = Repository<T>.Create();
So, nun meine Frage, ist die Factorymethod so wirklich eine schöne Lösung?
Für mich sieht das sehr "gehackt" aus, geht das schöner?
Und 2tens, um dieses ewsRepository zu benutzen, komme ich im NewsPresenter:DataPresenterBase<News> nicht um einen cast herum, oder?
ich hoffe ihr könnt mir die erleuchtung bringen...
mfg
serial
Hoi serial
IoC / DI 😃
Und nein, um den Cast kommst du nicht herum, wenn du auf dem Typen Repository<T> arbeitest.
Daher würde ich eher empfehlen, zumindest für das NewsRepository einen eigenen Kontrakt (Interface) zu benutzen, was dann auch z.B. IRepository<T> implementiert.
Danach: Entweder eigene Instanziierung oder IoC / DI.
Generalisierung ist gut und schön, aber in diesem Fall schadet sie dir mehr, als sie nützt.
Du kannst aber die Generalisierung (Repository<T> / IRepository<T>) nutzen, wo du nur das brauchst.
Ansonsten musst du casten oder erzeugst dir direkt ein NewsRepository.
Gruss Peter
--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011
Hi,
das sieht mir alles sehr kompliziert aus (Klassendesign).
Brauchst Du überhaupt solch generische Klassen?
Ich würde zusehen, dass ich bei
public abstract class DataPresenterBase<T> : PresenterBase, IDataPresenterBase where T:
das <T> loswerde.
Muss die Klasse abstrakt sein bzw. gibt es einen anderen Weg ohne abstrakte Klasse?
Versuche es mal ohne wheres und abstracts.
Falls nötig wie Peter schreibt mit Interfaces.
Ich kenne Deine Aufgabe nicht.
Von daher verzeih' diese plumpe Antwort.
Gruß, CoLo
Hallo,
das T brauch ich, da es ein Repository für Linq-Objekte ist, und ich hier den Linq-Typ als T angebe.
mfg
serial
also einerseits finde ich
public static Repository<T> Create()
{
if (typeof(T) == typeof(News))
return (Repository<News>)new NewsRepository() as Repository<T>;
return new Repository<T>();
}
relative umständlich
ein
return new NewsRepository();
reicht da vollkommen.
und bei einem where T: class bin ich auch leicht irretiert, das ist gerade soviel Einschränkung dass keine Valuetypes genommen werden können, aber dennoch sehr nahe bei object.
Ist das ein gewünschtes Verhalten?
mbg
Rossegger Robert
mehr fragen mehr wissen
Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen
ein ... reicht da vollkommen.
nein leider reicht das nicht, da es nicht implizit gecastet werden kann, darum brauch ich dieses konstrukt.
und bei einem where T: class bin ich auch leicht irretiert, das ist gerade soviel Einschränkung dass keine Valuetypes genommen werden können, aber dennoch sehr nahe bei object.
Ist das ein gewünschtes Verhalten?
Ja das ist gewollt, da ich keine basisklasse bzw interfaces für die linq-objekte besitze.
mfg
serial
richtig, sorry, aber beide Arten von cast brauchst Du nicht, es genügt das 'as'
und wenn das so gewollt ist, ich kenne natürlich nicht die genauen Anforderungen dann wird der code auch so passen.
Aber generell, wenn ich so einen Code schreibe, denke ich nochmal darüber nach ob ich nicht die Anforderungen an die Suche umgestalten kann.
mbg
Rossegger Robert
mehr fragen mehr wissen
Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen