Pergunta

Eu estou me preparando para iniciar um novo projeto asp.net web, e eu estou indo para LINQ to SQL. Eu fiz um pouco de trabalho recebendo minha configuração camada de dados usando algumas informações que encontrei por Mike Hadlow que usa uma interface e genéricos para criar um repositório para cada tabela no banco de dados. Eu pensei que esta era uma abordagem interessante à primeira vista. No entanto, agora eu acho que poderia fazer mais sentido para criar uma classe Repository base e herdar a partir dele para criar uma classe TableNameRepository para as tabelas que eu preciso de acesso.

Qual abordagem será permitir-me para adicionar funcionalidade específica a uma tabela de uma forma testável limpa? Aqui está minha implementação Repository para referência.

public class Repository<T> : IRepository<T> where T : class, new()
{
    protected IDataConnection _dcnf;

    public Repository()
    {
        _dcnf = new DataConnectionFactory() as IDataConnection;
    }

    // Constructor injection for dependency on DataContext 
    // to actually connect to a database
    public Repository(IDataConnection dc)
    {
        _dcnf = dc;
    }

    /// <summary>
    /// Return all instances of type T.
    /// </summary>
    /// <returns>IEnumerable<T></returns>
    public virtual IEnumerable<T> GetAll()
    {
        return GetTable;
    }

    public virtual T GetById(int id)
    {
        var itemParam = Expression.Parameter(typeof(T), "item");
        var whereExp = Expression.Lambda<Func<T, bool>>
            (
                Expression.Equal(
                    Expression.Property(itemParam, PrimaryKeyName),
                    Expression.Constant(id)
                ), new ParameterExpression[] { itemParam }
            );
        return _dcnf.Context.GetTable<T>().Where(whereExp).Single();
    }

    /// <summary>
    /// Return all instances of type T that match the expression exp.
    /// </summary>
    /// <param name="exp"></param>
    /// <returns>IEnumerable<T></returns>
    public virtual IEnumerable<T> FindByExp(Func<T, bool> exp)
    {
        return GetTable.Where<T>(exp);
    }

    /// <summary>See IRepository.</summary>
    /// <param name="exp"></param><returns></returns>
    public virtual T Single(Func<T, bool> exp)
    {
        return GetTable.Single(exp);
    }

    /// <summary>See IRepository.</summary>
    /// <param name="entity"></param>
    public virtual void MarkForDeletion(T entity)
    {
        _dcnf.Context.GetTable<T>().DeleteOnSubmit(entity);
    }

    /// <summary>
    /// Create a new instance of type T.
    /// </summary>
    /// <returns>T</returns>
    public virtual T Create()
    {
        //T entity = Activator.CreateInstance<T>();
        T entity = new T();
        GetTable.InsertOnSubmit(entity);
        return entity;
    }

    /// <summary>See IRepository.</summary>
    public virtual void SaveAll()
    {
        _dcnf.SaveAll();
    }

    #region Properties
    private string PrimaryKeyName
    {
        get { return TableMetadata.RowType.IdentityMembers[0].Name; }
    }

    private System.Data.Linq.Table<T> GetTable
    {
        get { return _dcnf.Context.GetTable<T>(); }
    }

    private System.Data.Linq.Mapping.MetaTable TableMetadata
    {
        get { return _dcnf.Context.Mapping.GetTable(typeof(T)); }
    }

    private System.Data.Linq.Mapping.MetaType ClassMetadata
    {
        get { return _dcnf.Context.Mapping.GetMetaType(typeof(T)); }
    }
    #endregion
}
Foi útil?

Solução

eu estaria tentado a sugerir que se você usar tipos de betão ou não deve não importa, como se o seu usando a injeção de dependência (castelo?) Para criar repositórios (assim você pode envolvê-los com diferentes caches etc), então seu codebase será nenhum o mais sábio do jeito que você fez isso.

Em seguida, basta pedir a sua DI para um repositório. Por exemplo. para castelo:

public class Home {
  public static IRepository<T> For<T> {
    get {
      return Container.Resolve<IRepository<T>>();
    }
  }
}

Pessoalmente, eu não inferior os tipos até encontrar uma necessidade.

Eu acho que a outra metade da sua pergunta é se você pode facilmente fornecer uma na implementação de memória de IRepository para testes e fins de armazenamento em cache. Por isso eu iria assistir como linq-to-objetos pode ser lento e que você pode encontrar algo como http: // www .codeplex.com / i4o útil.

Outras dicas

Você não deve criar um repositório para cada mesa.
Em vez disso, você deve criar um repositório para cada 'root entidade' (ou raiz agregada) que existe em seu modelo de domínio. Você pode aprender mais sobre o padrão e ver um exemplo de trabalho aqui:

http://deviq.com/repository-pattern/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top