Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Repository, specification, visitor e un abuso di Generics

12 views
Skip to first unread message

Giulio Petrucci

unread,
Sep 5, 2013, 8:50:45 AM9/5/13
to
Ciao a tutti,

sto seguendo l'ispirazione (tutta teorica) di implementare una
interfaccia che possa definire il comportamento di un repository. La
situazione è questa:

1. definizione di entità e specification
public interface IEntity<TKey>
{
TKey Key { get; }
}
public abstract class Entity<TKey> : IEntity<TKey>
{
public TKey Key { get; private set; }
}
public interface ISpecification<T>
{
bool IsSatisfiedBy(T item);
}

2. per ogni entità definisco una gerarchia di specification e un visitor
public class Foo : Entity<Int32>
{
public Int32 Seed { get; set; }
}
public interface IFooSpecification : ISpecification<Foo>
{
T Accept<T>(IFooSpecificationVisitor<T> visitor);
}
public class SeedNonZeroFooSpecification : IFooSpecification {
public bool IsSatisfiedBy(Foo item) {
return item.Seed != 0;
}
public T Accept<T>(IFooSpecificationVisitor<T> visitor)
{
return visitor.Visit(this);
}
}
public interface IFooSpecificationVisitor<T> {
T Visit(SeedNonZeroFooSpecification spec);
}

Ora, vorrei creare una interfaccia che implementata permetta di
generalizzare (tramite type arguments) quanto segue:

public interface IFooRepository
{
Foo Get(Int32 key);
void Add(Foo foo);
IEnumerable<Foo> Select(IFooSpecification spec);
}

Per fare tutto ciò dovrei avere una cosa del genere:

public interface IRepository<TEntity, TKey, TSpecification>
where TEntity : IEntity<TKey>
where TSpecification : ISpecification<TEntity>
{
TEntity Get(TKey key);
void Add(TEntity entity);
IEnumerable<TEntity> Select(TSpecification specification);
}
public class FooRepository : IRepository<Foo, Int32, IFooSpecification>
{
public Foo Get(Int32 key) { ... }
public void Add(Foo entity) { ... }
public IEnumerable<Foo> Select(IFooSpecification specification) { ... }
}

Domande. :-)
1. è possibile far capire al compilatore che visto che il primo type
argument è Foo, il secondo dovrà necessariamente essere Int32?
(risposta: No, ma tanto valeva chiedere)
2. tutto questo, onestamente, ha senso? :-)

Ciao e grazie,
Giulio

--

0 new messages