[altnet-hispano] Re: [NHibernate-Hispano] NHV

已查看 32 次
跳至第一个未读帖子

Edgar Ramos

未读,
2010年5月15日 15:09:322010/5/15
收件人 altnet-...@googlegroups.com
Jose

Tengo muchas preguntas pero voy con lo basico

Al igual que tu busco la forma en que mis entidades sea POCOS (puros
por llamarlos asi), no me busca poner codigo para validacion y otros
(InotifyPropertyChance, IDataError) con estas clases

En la aplicacion chinooWindowsForm o WP, existe de antemano un
binding, algo que no se presenta en una aplicacion asp net mvc (espero
estar en lo cierto, si me equivoco me corrigen por favor), aqui la
pregunta, si requiero validar mis entidades o mis viewmodels tengo que
implementar INotiyPropertyChange ?

Si lo requiero puedo inyectar este comportamiento de la forma que lo
expones en chinooWP mediante el unaddins que esta creado ?

Y de paso tambien inyectar el comportamiento de IDataError ?

Gracias nuevamente


El día 12 de mayo de 2010 10:59, Edgar Ramos <eramo...@gmail.com> escribió:
> Sabia que algun dia tenia que ir a unhaddins, siempre me pregunte que
> es eso (yo y mi ignorancia), bueno despues de leer de forma
> exponencial y revizar codigo como por ejemplo chinoowinform (couple),
> leer sobre DDD y revizar otro codigo de ejemplo
> http://blogs.msdn.com/cesardelatorre/archive/2010/03/11/our-new-net-4-0-ddd-n-layer-architecture-app-example.aspx,
> me dije bueno ya que en un par de ocaciones gente de la lista me ha
> dicho que tengo todo acoplado en mi codigo, era hora de aprender hacer
> las cosas bien.
>
> Y comence por la capa de dominio, Domian.Core, viendo chinoo, me dije
> que pleno como han desarrollado la parte en donde hago a mis clases
> entidades, es decir que tenga es Id, que necesitaran todas mis
> entidades que persistiran datos (espero estar escribiendo bien, pero
> si me equivoco corrijanme por favor), asi que pense en sacar estas
> clases/interfaces a una dll aparte :)
>
> Pero que equivocado estaba, esto tambien esta en unhaddins, lo
> encontre revizando chinooMediaManager (WP) :))
>
> Mi objetivo final sera utilizar  ServiceLocator
> http://commonservicelocator.codeplex.com/, con la implementacion de
> Castle, mas unhaddins.Entity y la parte de Validacion
>
> Sigo observando el codigo y aprendiendo a la vez
>
> saludos y gracias nuevamente
>
>
>
> El día 10 de mayo de 2010 18:46, José F. Romaniello
> <jfroma...@gmail.com> escribió:
>> A mi me encanta hablar de estos temas:
>> http://jfromaniello.blogspot.com/2010/02/idataerrorinfo-service-locator-way.html
>> Yo registro un IEntityValidator (esto lo hizo y lo explicó Fabio Maulo aca)
>> en mi container de IoC y luego lo accedo con ServiceLocator.
>> En unhaddins tenemos muchas implementaciones de IEntityValidator (Castle
>> Validations, Data Annotations, Validation Application Block etc)
>> No me gusta en mi dominio tener referencias a NHV (que a su vez tiene
>> referencias a NH).
>>
>>  Respondiendo a tus preguntas:
>>>
>>> - Sigue la misma logica de validación en una aplicacion asp net mvc ?
>>>
>>> (validacion de mis entidades con nhv en mis controllers)
>>
>> Si, funciona exactamente igual. Si el model de asp.net mvc implementa
>> IDataErrorInfo no hace falta nada más. Y acá hago una observación muy
>> importante OJO con usar Entidades como ViewModels, no te recomiendo ese
>> camino. Por otro lado, usando xVal podes hacer que tus validaciones esten en
>> el lado del cliente también, javascript.
>>
>>>
>>> - Ya no requiero utilizar ModelState.IsValid ?
>>
>> Claro que lo tenes que usar, si tu Model implementa IDataErrorInfo, al
>> preguntar ModelState.IsValid lo controla a través de los métodos de
>> IDataErrorInfo
>>>
>>> - O requiero complementar la validacion como algo similar a esto   if
>>>
>>> (ModelState.IsValid && employee.IsValid()) ?
>>
>> ModelState.IsValid alcanza.
>>>
>>> - Ya que estoy organizando mi aplicacion en n-layers y requiero
>>>
>>> utilizar nhv, me parece haber visto en el blog de Jose la forma de
>>>
>>> implentar una interface que sugiere Fabio
>>>
>>>  para lograr este objetivo, pero no la encuentro
>>
>> http://fabiomaulo.blogspot.com/2009/11/validation-abstraction-custom.html
>> La implementación IEntityValidator para NHV esta en unhaddins, mas
>> concretamente aquí:
>> http://code.google.com/p/unhaddins/source/browse/#svn/trunk/uNhAddIns/uNhAddIns.NHibernateValidator
>>
>> --
>> Para escribir al Grupo, hágalo a esta dirección:
>> NHibernat...@googlegroups.com
>> Para más, visite: http://groups.google.com/group/NHibernate-Hispano
>

--
Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano" de Grupos de Google.
Para publicar una entrada en este grupo, envía un correo electrónico a altnet-...@googlegroups.com.
Para anular tu suscripción a este grupo, envía un correo electrónico a altnet-hispan...@googlegroups.com
Para tener acceso a más opciones, visita el grupo en http://groups.google.com/group/altnet-hispano?hl=es.

José F. Romaniello

未读,
2010年5月15日 16:22:572010/5/15
收件人 altnet-...@googlegroups.com
Para que tus clases puedan validarse en ASP.net MVC no necesitas INotifyPropertyChanged.
No te recomiendo usar dynamicproxy, ni lo que esta actualmente en unhaddins para implementar IDataErrorInfo.
Lo que te conviene es ponerlo en tu clase base, son dos metodos nomas, y de ahi llamar al servicelocator, como te mostre en este post, http://jfromaniello.blogspot.com/2010/02/idataerrorinfo-service-locator-way.html

Edgar Ramos

未读,
2010年5月15日 16:25:142010/5/15
收件人 altnet-...@googlegroups.com
Gracias Jose, sigo avanzando

El día 15 de mayo de 2010 15:22, José F. Romaniello

Edgar Ramos

未读,
2010年5月18日 18:24:152010/5/18
收件人 altnet-...@googlegroups.com
Gracias José

La verdad me toco leer bastante pero he logrado hacerlo funcionar,
todavia me falta separar bien en capas, pero las configuraciones
actuales trabajaron sin problema

utilice todo el codigo que sugeriste con la clase BaseEntity que
hereda de IDataErrorInfor, Entity de uNhAddIns.Entities
http://jfromaniello.blogspot.com/2010/02/idataerrorinfo-service-locator-way.html

utilice el uNhAddIns.Adapters, uNhAddIns.NHibernateValidator,
uNhAddIns.NHibernateTypeResolver
utilice el codigo que sugiere Fabio en su blog
http://fabiomaulo.blogspot.com/2009/11/validation-abstraction-custom.html
y tambien este http://fabiomaulo.blogspot.com/2009/11/guywire.html

mas lo que hiciste en ChinooWP, con la interface IConfigurator

Bueno a mas de reutilizar ese codigo, costo trabajo entender esa forma
tan chevere que tienen para programar y los diferentes conceptos de
por medio

Gracias nuevamente y a todos quienes colaboraron en los proyectos de
uNhAddIns, la verdad que se aprende bastante revizando codigo

saludos


El día 15 de mayo de 2010 15:22, José F. Romaniello

José F. Romaniello

未读,
2010年5月18日 18:41:502010/5/18
收件人 altnet-...@googlegroups.com
Me alegro mucho che! 

Una cosa que mencionaste en un momento y que se puede mejorar, cuando hice el guywire de Chinook desconocía que windsor ya tenía una interfaz como la que invente, se llama IWindsorInstaller fijate aca: http://blog.ploeh.dk/2010/01/26/IWindsorInstaller.aspx

en la proxima versión de castle bastara hacer esto:

container.Install(FromAssembly.This())

para ejecutar todos los installer

Edgar Ramos

未读,
2010年5月19日 10:22:242010/5/19
收件人 altnet-...@googlegroups.com
Genial José

Esta lista y gente como tu me alegran mis dias, ya me pongo a
investigar, mi siguiente paso es comenzar a dividir en capas mi
aplicacion, quiero hacer algo un poco al estilo DDD (sigo consultando
...), en la parte de mi dominio, esta ya mas o menos avanzada el
Domain.Core, con la estructura y organizacion de mis interfaces, no
encuentro claro, o diferencia entre DAO o Repository, y mas aun el
hacer que estos contratos den la pauta para una implementacion con el
patron Specification

Lo que veo claro es lo siguiente, en cada layer, será requerido si o
si Servicios, los cuales seran los unicos que se comuniquen con mis
implementaciones, y aqui una duda, estos servicios serán algo asi como
en chinooWP el AlbumManagerModel ?, me ayudaria tambien algun ejemplo
de un EntityRoot (creo que se escribe asi) y como organizarlo con mi
servicio antes mencionado
bueno en fin a seguir investigando ...

Saludos y Gracias a todos nuevamente

PD: Gracias a mi buen amigo Nelo http://nelopauselli.blogspot.com/, el
codigo de su aplicacion ha sido mi punto de partida

El día 18 de mayo de 2010 17:41, José F. Romaniello

José F. Romaniello

未读,
2010年5月19日 11:33:222010/5/19
收件人 altnet-...@googlegroups.com
la diferencia entre repository y dao es que Repository representa una colección en memoria, en chinook use repository, esto queda claro en esta interface:


el mismo repositorio es un "IQueryable". 

Últimamente estoy un poco peleado con este patron y uso dao, el dao no implementa iqueryable, pero tiene dos metodos 
IQueryable<T> Retrieve(Expression<Func<T, bool>> predicate);
IQueryable<T> Count(Expression<Func<T, bool>> predicate);

podes leer más aca:

Acerca del patrón especificación, lo podes usar con cualquiera de los dos patrones, y si vas a usar linq, te recomiendo mirar esto que acabo de publicar en codeplex hace 3 días:
http://linqspecs.codeplex.com/ (perdón por la propaganda)


P.S. Ya que te esta gustando todo esto que estas aprendiendo, estaría bueno que te escribas unos posts :D.

Edgar Ramos

未读,
2010年5月19日 11:36:592010/5/19
收件人 altnet-...@googlegroups.com
Nuevamente Gracias José

La idea de los post me andaba sonando pero estoy con un poco de miedo
para serte sincero, debido a que mi nivel recien es basico, eso de
tener un blog tambien me gusto, a ver si me animo con todo

saludos

El día 19 de mayo de 2010 10:33, José F. Romaniello

Carlos Peix

未读,
2010年5月19日 11:42:212010/5/19
收件人 altnet-hispano
Hola Jose,

Por ahi esta peleado con repository porque te estas limitando a una definicion mucho mas restrictiva que lo que pensaron Fowler, Evans y otros.

Cuando ellos pensaban esto, IQueryable no existia, por eso definieron que un repositorio debe tener "semantica" de coleccion. Yo agregaria que debe tener una semantica en su protocolo asimilable a la semantica de protocolo de una coleccion.

Por ejemplo, no necesariamente un repositorio debe tener un metodo Add, pero si tuviera la posibilidad de agregar elementos, deberia seguir esa linea.

Abrazo

----------------------------------
Carlos Peix

2010/5/19 José F. Romaniello <jfroma...@gmail.com>

José F. Romaniello

未读,
2010年5月19日 11:51:182010/5/19
收件人 altnet-...@googlegroups.com
Si, entiendo mi equivocación, 


El 19 de mayo de 2010 12:42, Carlos Peix <carlo...@gmail.com> escribió:
Cuando ellos pensaban esto, IQueryable no existia, por eso definieron que un repositorio debe tener "semantica" de coleccion. Yo agregaria que debe tener una semantica en su protocolo asimilable a la semantica de protocolo de una coleccion.

Para decirlo en criollo la interfaz de un Repository tiene que ser similar a la interfaz de una collection. 
Lo cual hoy en día se facilita implementando IQueryable + un par de metodos más. Antes de iqueryable, era un poco mas engorroso, y a veces los limites entre dao y repository eran mas difusos.

Carlos Peix

未读,
2010年5月19日 12:06:452010/5/19
收件人 altnet-hispano
Coincido

----------------------------------
Carlos Peix

2010/5/19 José F. Romaniello <jfroma...@gmail.com>
Si, entiendo mi equivocación, 

Cristian Prieto

未读,
2010年5月19日 12:34:192010/5/19
收件人 altnet-...@googlegroups.com
Hola José, Carlos, Edgar

Totalmente deacuerdo con la definición de Carlos, cuando Fowler y Evans hablaban de repositorio no existían cosas como IQueryable, entonces actualmente uno se pelea tratando de implementar repositorios que tengan miles de métodos y/o jugar con specifications o generar tu propio Query Object.

Algo que me llamó la atención fue la forma en que Edgar esta llevando a cabo las validaciones en su aplicación MVC, si entendí bien, el esta dejando la responsabilidad de la entidad el validarse, en otras palabras, algo como:

customer.IsValid();

Me imagino entonces que uno de sus controladores tendría su forma algo así:

public ActionResult Add(Customer customer) {
     if (customer.IsValid()) {
         _customerRepo.Add(customer);
        // Blah blah blah
     } 
    // Blah blah
}

Para la mayoría de veces una acción como esta sería suficiente y bastaría, digamos en una gran mayoría de casos, pero tengo un par de cosas que quisiera agregar sobre este proceso de "entidad-validación-repositorio".

No entiendo porqué la mayoría de ejemplos (de microsoft y de terceros) incluyen el repositorio de manera directa en el controlador, bueno, probablemente porque los ejemplos son solamente ejemplos y son bastante sencillos, por eso siempre vemos que se hace un binding directo al objeto Customer y luego se agrega en el repositorio, totalmente deacuerdo que para algo simple es el mejor approach.

Por lo general, nuestros objetos de dominio son (o deberian ser) ricos en comportamiento, contener data y estado si, pero encapsular el comportamiento del dominio en ellos. Lo que nosotros obtenemos o mostramos en la vista no requiere tal comportamiento (y si requiere son cosas muy apegadas a la vista como "formatea este url para que se parezca a esto"). Coincido que la validación del objeto es una responsabilidad del objeto en si, pero por otro lado sigo considerando a la inclusión del ServiceLocator como una mal practice (claro, como todo se que hay excepciones y esta podría ser una de ellas), el detalle (además del asunto del ServiceLocator) es que por lo general debes validar concers que solamente le incumben a la presentación, no al dominio. Por ello, a menos que sean casos excepcionales, hago una distinción entre los objetos de dominio y los proyectados a la vista, dejando que el DTO sea quien se valide y luego el objeto de dominio haga sus validaciones de negocio respectivas.

Por ejemplo:

[Transactional]
public ActionResult Add(CustomerAddDTO customer) {
    if (Model.IsValid) {
        _customerManagementService.AddCustomer(customer);  // si se viola una regla de negocio, throws
    }
    // Blah blah
}

Nota que el CustomerDTO no se valida así mismo, ese es trabajo de un ModelBinder customizado que a su vez puede usar un validator injectado para que lo haga (o usar el ServiceLocator dentro del ModelBinder).

No estoy diciendo que "permear" las entidades en el modelo de negocios sea malo, simplemente hay momentos en que tal caso no se permite, por ejemplo, la típica forma de login:

public ActionResult Login(string username, string password, bool remember, string returnUrl) {
    // Aqui va lo demás
}

Probablemente username y password pertenezcan a la entidad Customer, pero definitivamente las otras dos no. Tanto username y password tienen reglas de validación, hacerlo dentro del controlador simplemente no esta bien. Es cuando entonces tiene mayor sentido algo como:

[Transactional, HttpPost]
public ActionResult Login(LoginDTO login) {
    if (Model.IsValid) {
        // Blah
    }
    // More blah
}

¿Comprenden mi punto? ¿estoy fuera de lugar? ¿me dormí en la clase? ¿los aburrí hoy?

Por otro lado, Edgar, vas por buen camino :)


Saludos!

-- Cristian


2010/5/19 José F. Romaniello <jfroma...@gmail.com>
Si, entiendo mi equivocación, 

José F. Romaniello

未读,
2010年5月19日 12:42:322010/5/19
收件人 altnet-...@googlegroups.com
Es totalmente CIERTO lo que decis y por eso en mi primer mail dije:

Si, funciona exactamente igual. Si el model de asp.net mvc implementa IDataErrorInfo no hace falta nada más. Y acá hago una observación muy importante OJO con usar Entidades como ViewModels, no te recomiendo ese camino. Por otro lado, usando xVal podes hacer que tus validaciones esten en el lado del cliente también, javascript.


-Implementar IDataerrorInfo facilita el hecho de mostrar los errores al usar Databinding
-DataBinding entre UI y entidades de dominio... Guarda!

A eso que vos llamas DTO yo lo llamo viewmodel.

Edgar Ramos

未读,
2010年5月19日 14:21:212010/5/19
收件人 altnet-...@googlegroups.com
Cristian

Mi primer enfoque fue ese justamente no validar de esta forma
customer.IsValid(); y luego algo como esto en el action de mis
controllers

public ActionResult Add(Customer customer) {
if (customer.IsValid()) {
_customerRepo.Add(customer);
// Blah blah blah
}
// Blah blah
}

Coincido plenamente contigo
--------------------
Por ello, a menos que sean casos excepcionales, hago una distinción
entre los objetos de dominio y los proyectados a la vista, dejando que
el DTO sea quien se valide y luego el objeto de dominio haga sus
validaciones de negocio respectivas.
---------------------

E igual forma sugeria José llamandolo viewModels, con este ejemplo que expones

public ActionResult Add(CustomerAddDTO customer) {
if (Model.IsValid) {
_customerManagementService.AddCustomer(customer); // si se
viola una regla de negocio, throws
}
// Blah blah
}

Es precisamente a lo que queria llegar, bueno ya llegue, ahora me
falta la linea esta linea
_customerManagementService.AddCustomer(customer), voy avanzando poco
a poco, tratando de digerir todo (investigar, entender, y llevarlo a
codigo con buenas practicas)

Ahora al a ver expuesto lo siguiente [Transactional, HttpPost], la
parte Transactional, no la he entendido bien, me ayudaria un link para
investigar

Con lo siguiente
--------------
Nota que el CustomerDTO no se valida así mismo, ese es trabajo de un ModelBinder
------------

En el ejercicio que hice efectivamente lo he comprobado, pero para
esto mi viewModel (como lo expresa José) debio implementar
IDataErrorInfo, tengo que adminitirlo por hoy mi ejemplo se realizo
sobre una entidad, esta parte precisamente
------------------
public ActionResult Add(Customer customer) {,
-------------------------------------------
mi idea sera luego utilizar viewModel o DTO ?, no lo se o si son lo
mismo, porque se llaman diferente ?

Por cierto no tengo en ninguna parte de mi codigo algo similar a esto
Customer.IsValid()

Con lo siguiente
----------------------
ModelBinder customizado que a su vez puede usar un validator injectado
para que lo haga (o usar el ServiceLocator dentro del ModelBinder).
---------------------

Lo del ModelBinder customizado lo lei en un post que no lo encuentro
este momento, para ir aumentando a mi lista de cosas pendientes me
viene bien otro link

Saludos y Gracias

PD: Siempre estos comentarios me alimentan y me hace ver que una de
las mejoras cosas que pude hacer es encontrar alnet, y en hora buena
esta en español

Cristian Prieto

未读,
2010年5月19日 15:08:042010/5/19
收件人 altnet-...@googlegroups.com
Si tu modelo es "simple enough" y tu lógica como tal es así de simple, go ahead :)

-- Cristian


2010/5/19 Edgar Ramos <eramo...@gmail.com>

Diego Mijelshon

未读,
2010年5月20日 10:04:072010/5/20
收件人 altnet-...@googlegroups.com
Me hiciste pensar que sería interesante (y nada complicado) hacer una implementación de un repositorio con esta interfaz:

public interface IRepository<TEntity, TIdentity> : IQueryable<TEntity>, ICollection<TEntity>, IDictionary<TIdentity, TEntity> where TEntity : IEntity<TIdentity>

Jugando un poco con las posibilidades tanto de DAO como de Repository, más el agregado de IDictionary para operaciones como delete por key
En este último caso, no todos los métodos tienen sentido, pero es un lindo experimento... después les cuento :-)

   Diego


2010/5/19 José F. Romaniello <jfroma...@gmail.com>
Si, entiendo mi equivocación, 

José F. Romaniello

未读,
2010年5月20日 10:45:132010/5/20
收件人 altnet-...@googlegroups.com
Este repositorio implementa IQueryable<TEntity>


Opte como por wrappear todos los métodos del queryable de nhibernate. Y usa SessionFactory.GetCurrentSession(), lo cual esta bueno por que toma la session del contexto, sea web, thread o .. que se yo CpBT.

(no implementa IDictionary ni ICollection)

Diego Mijelshon

未读,
2010年5月20日 10:52:082010/5/20
收件人 altnet-...@googlegroups.com
Sí, lo vi y estoy armando una implementación tomando eso como base.

   Diego


2010/5/20 José F. Romaniello <jfroma...@gmail.com>

Edgar Ramos

未读,
2010年5月20日 12:13:152010/5/20
收件人 altnet-...@googlegroups.com
Genial todos los aportes son bienvenidos

Avanzando con la organización y estructura de mis layers en este
proyecto asp net mvc, me encuentro aqui.

un Assembly cuyo namespace es Domain.Entities, este al menos me parece
ya terminado pero se me presento lo siguiente "Contratos de
Repositorios", leyendo los articulos que me enviaron, como este de
Fabio
http://fabiomaulo.blogspot.com/2009/09/repository-or-dao-dao.html

En donde comenta lo siguiente "Because the pattern does not define how
a DAO should look", entonces tengo el ejemplo de José que me ha
gustado mucho

public interface IRepository<T> : IQueryable<T>
{
T Get(object id);
T Load(object id);
T MakePersistent(T entity);
void Refresh(T entity);
void MakeTransient(T entity);
}

y aqui una pregunta, el extender IQueryable<T>, me ayudaría en un
futuro a no realizar algo como esto, de la forma siguiente verdad ?
FindByDecription, FindByPrice, FindByName, FindByCriteria, y Fabio
sugiere lo siguiente

IEnumerable<TEntity> Retrieve(Expression<Func<TEntity, bool>> predicate);
int Count(Expression<Func<TEntity, bool>> predicate);

y José me ayuda con esto

IQueryable<T> Retrieve(Expression<Func<T, bool>> predicate);
IQueryable<T> Count(Expression<Func<T, bool>> predicate);

Primero tengo que investigar este codigo para entenderlo, cualquier
opinion es muy valiosa

Por otro lado, en chinookWP, José crea IRepository<T> : IQueryable<T>
en el Assembly ChinookMediaManager.Data y su respectiva implementacion
con NH en ChinookMediaManager.Data.Impl, con Repository
Mi idea podria ser reutilizar IRepository y su implementacion como
base en todos mis proyectos en donde utilice NH, pero no requiero
crearlos cada vez que lo necesite, es buena idea sacarlos a un
assembly separado ?

Gracias nuevamente

El día 20 de mayo de 2010 09:52, Diego Mijelshon
<di...@mijelshon.com.ar> escribió:

José F. Romaniello

未读,
2010年5月20日 13:08:042010/5/20
收件人 altnet-...@googlegroups.com
El 20 de mayo de 2010 13:13, Edgar Ramos <eramo...@gmail.com> escribió:
y aqui una pregunta, el extender IQueryable<T>, me ayudaría en un
futuro a no realizar algo como esto, de la forma siguiente verdad ?
FindByDecription, FindByPrice, FindByName, FindByCriteria, y Fabio
sugiere lo siguiente

Sea que use Dao (con Retrieve y Count pero sin implementar IQueryable para este ejemplo) 
o sea que use Repository (sin Retrieve y sin Count pero implementando IQueryable para este ejemplo)
Sea cual sea de las dos opciones, yo no pongo en mis repositorios FindByDescription(...);

Con DAO:
   miDaoDeProductos.Retrieve(p => p.Description == xxx);
Con repository:
   miRepoDeProductos.Where(p => p.Description == xxx); 
En el caso de repository, "Where" es un extension method de Linq, definido en System.Linq. No hace falta crear nada.

Y para organizar queries mas complejas utilizo mi librería http://linqspecs.codeplex.com/



 .........y Fabio sugiere lo siguiente
 
IEnumerable<TEntity> Retrieve(Expression<Func<TEntity, bool>> predicate);
int Count(Expression<Func<TEntity, bool>> predicate);
 
y José me ayuda con esto
 
IQueryable<T> Retrieve(Expression<Func<T, bool>> predicate); 
IQueryable<T> Count(Expression<Func<T, bool>> predicate);



Lo que yo sugerí, es lo mismo que Fabio sugiere, (de hecho... él me lo sugirió a mi y yo lo empece a usar je!)
Cuando escribí ese mail me debo haber confundido y puse IQueryable para el coutn, cuando en realidad es "int" para el count.

La diferencia entre devolver IEnumerable e IQueryable es para hacerlo un poco mas explicito, ya que IQueryable : IEnumerable....

Cristian Prieto

未读,
2010年5月20日 13:17:242010/5/20
收件人 altnet-...@googlegroups.com
Comence a escribir una respuesta hace un rato al respecto, pero terminé con un mail tan largo que se transformó en post de mi blog


En resumidas cuentas, usar Dao con IQueryable<T> a mi criterio esta rebien, exponerlo es lo que no comparto.

¡Saludos!

-- Cristian


2010/5/20 José F. Romaniello <jfroma...@gmail.com>
El 20 de mayo de 2010 13:13, Edgar Ramos <eramo...@gmail.com> escribió:

Diego Mijelshon

未读,
2010年5月20日 13:18:482010/5/20
收件人 altnet-...@googlegroups.com
OK, ya lo tengo más o menos andando...

Lo subí a http://gist.github.com/407818, se acepta feedback de todo tipo.

   Diego


2010/5/20 Diego Mijelshon <di...@mijelshon.com.ar>

Omar del Valle Rodríguez

未读,
2010年5月20日 13:35:142010/5/20
收件人 altnet-...@googlegroups.com

Hace mucho que llegué a la misma conclusión que Cristian..  Genial el artículo…

 

;)

José F. Romaniello

未读,
2010年5月20日 14:26:092010/5/20
收件人 altnet-...@googlegroups.com
Si, no, que se yo. Hay como que buscar un balance, al hacer la api más rígida como vos lo expones, vas perdiendo flexibilidad. 
Y hay que ver hasta que punto se justifica sacrificar flexibilidad.

El hecho de tener este método;
IQueryable<T> Retrieve(Expression<Func<T, value>> predicate)

es por que si en vez de iqueryable retornas ienumerable, y luego le aplicas otra cosa.. hagamos este ejemplo:

dao.Retrieve(x => x.Description.Contains("arrs").Any(x => x.Price < 10)

En ese caso tu Any recibe Func<T, bool> en lugar de Expression<Func<T, bool>>... y eso que significa?, como Func es un delegado y no una expression, se tiene que enumerar la consulta (hasta el where) y ejecutarse localmente. Si haces que devuelva IQueryable el Any es en la base de datos, con un Exists. (Por favor que alguien me corrija si estoy equivocado)

PS; como diría un amigo mio, "IPageable" suena fuerte. Ni me anime a ver los métodos que tenía.

José F. Romaniello

未读,
2010年5月20日 14:28:532010/5/20
收件人 altnet-...@googlegroups.com
Barbaro Diego! aunque el método Clear me da un poco de cagaso.

Diego Mijelshon

未读,
2010年5月20日 14:43:572010/5/20
收件人 altnet-...@googlegroups.com
Sí, honestamente lo pensé varias veces a ver si lo implementaba o lo dejaba lanzando NotImplementedException... pero me quedé con la filosofía "sharp tools, si te cortás es tu problema" :-)

Cristian Prieto

未读,
2010年5月20日 14:52:462010/5/20
收件人 altnet-...@googlegroups.com
Va, que te parece IPagineable<T>? suena mejor no? :P

En cuanto a exponer métodos extra, si tienen razón al indicar que como developer no hay que protegerte, si no darte las herramientas, allá vos que hagas con ellas... El problema radica no en "proteger" al developer, si no en la "semántica" que expones... Es muy diferente decir "IEnumerable<T> because I really know what I'm doing inside and you are not going to need anything else" a decir "IQueryable<T>, do whatever you want to do, go, drink from my beer and sit on my sofa", si bien la última es totalmente aceptable para tus "familiares" no lo es para "extraños" (en este caso digamos que los familiares son entidades e ideas relacionadas con el negocio, mientras que extraños son consumidores finales como la interface de usuario)....

¿Un ejemplo típico? qué te parece un servicio... o acaso todo eso no se aplica a servicios de WCF?


Como diría mi profesora de lengua española, "las palabras tienen un gran poder, aprendalas a usar"...

¡Saludos!


-- Cristian Prieto
回复全部
回复作者
转发
0 个新帖子