Ich versuche, einige repetitive Code herauszufiltern, aber es fängt jetzt an, funky zu riechen. sagen, dass ich mit diesem nicht ganz richtig beginnen, aber Sie meine Drift zu fangen:Refactoring, um doppelten Code zu vermeiden
public virtual OrganisationEntity Get(int id)
{
SqlCommand command = new SqlCommand();
command.CommandText = @"SELECT t.Id, t.Description FROM Organisation t Where t.Id = @Id";
command.Parameters.Add("@id", SqlDbType.Int).Value = id;
List<OrganisationEntity> entities = new List<OrganisationEntity>();
SqlDataReader reader = Database.ExecuteQuery(command, ConnectionName.Dev);
while (reader.Read())
{
OrganisationEntityMapper mapper = Mapper;
entities = mapper.MapAll(reader);
}
return entities.First<OrganisationEntity>();
}
Es ist ziemlich offensichtlich jede andere Get (int id) Methode hat, abgesehen von der Abfrage die gleiche Form, so dass mein nächster Schritt würde sein, um eine Basisklasse zu machen, sucht RepositoryBase wie:
public abstract class RepositoryBase<T> where T : new()
{
/// <summary>
///
/// </summary>
public abstract EntityMapperBase<T> Mapper { get; }
public virtual T Get(int id)
{
List<T> entities = new List<T>();
SqlDataReader reader = Database.ExecuteQuery(Command, ConnectionName);
while (reader.Read())
{
EntityMapperBase<T> mapper = Mapper;
entities = mapper.MapAll(reader);
}
return entities.First<T>();
}
}
einige generischen Funkyness hinzuzufügen, aber das ist auch, wo es hässlich wird. Zuerst erwartet Database.ExecuteQuery einen SqlCommand und eine Enum, also dachte ich, ok, dann füge ich zwei Eigenschaften hinzu, die ich einfach mit ein paar Sachen starten werde. THe merke ich brauche den int id Parameter hier nicht mehr, da ich die Abfrage in einer Unterklasse konstruiere, also könnte ich genauso gut den Befehl und connectionName als Parameter übergeben, ich möchte den connectionName trotzdem vom OrganisationRepository abhängig machen (andere brauchen eine andere Zeichenfolge):
public class OrganisationRepository : RepositoryBase<OrganisationEntity>
{
protected override EntityMapperBase<OrganisationEntity> Mapper
{
get
{
return new OrganisationMapper();
}
}
public override OrganisationEntity Get(int id)
{
SqlCommand command = new SqlCommand();
command.CommandText = @"SELECT t.Id, t.Description FROM Organisation t Where t.Id = @Id";
command.Parameters.Add("@id", SqlDbType.Int).Value = id;
return base.Get(command, ConnectionName.Dev);
}
}
Aber oops, natürlich, jetzt die Methodensignaturen sind nicht mehr synchron ... oops! Also, im Grunde frage ich mich. Es fühlt sich einfach unangenehm an, weiß aber nicht genau warum. Auf der einen Seite möchte ich Repetitive-Code so viel wie möglich herausfiltern, aber jetzt lässt es mich damit!
Wie reformiere ich dies zu (mehr) richtigen OO? Sollte ich einfach vergessen, die Abfragezeichenfolgen herauszufiltern und viele Duplikate zu schreiben?
In Ihrem ersten Beispiel, was ist 'T'? –
Es sollte OrganizationEntity lesen, Bug kopieren;) es ist ein allgemeines Beispiel dafür, wo ich angefangen habe. – Oxymoron