- Testabilità: utilizzando il repository pattern otteniamo un layer su cui è semplice sostituire i dati con delle classi stub per effettuare test sulla logica di business senza interessare il codice di accesso ai dati.
- Astrazione: questa atrazione permette di modificare di disaccoppiare la logica di business dallo strato di accesso ai dati.
- Dependency Injection: permette di utilizzare containers Di per iniettare oggetti che si vogliono utilizzare nel codice.
In questo caso abbiamo solo operazioni di "select", in generale avremo tutte le operazioni cosidette CRUD (create, read, update, delete).public interface IShopRepository
{
IList<Shop> FindAll();
IList<Shop> FindAll(int index, int count);
IList<Shop> GetShopByCategory(int idcategory);
IList<Shop> GetPrimoPiano();
IList<Shop> GetAltri();
Shop FindById(int id);
Shop FindByName(string name);
IList<Category> GetAllCategory();
IList<Product> GetProductBoxMostSell();
IList<ShopAffiliato> GetAllShopAffiliati();
(...)
}
Il secondo passo è costruire una classe che implementa i metodi definiti nella interfaccia. Nel mio caso questa classe interagisce con l'ORM sottostante: Entity Framework.
Ora non rimane che dire implementare nel layer dei servizi una classe che istanzi un oggetto di tipo IShopRepository e ne utilizzi i metodi per ottenere collezioni che possibilmente abbiano implementata l'interfaccia IEnumerableIList<Shop> IShopRepository.FindAll()
{
var negozi = from n in new IperclubShopEntities().tShops
where n.attivo == true
select new Shop
{
Id = n.ShopId,
Nome = n.nome,
Attivo = (bool)n.attivo,
CodiceZanox = n.codicezanox,
Descrizione = n.descrizione,
Logo1 = n.logo1,
Logo2 = n.logo2,
PrimoPiano = (bool)n.primopiano,
ScopriAltri = (bool)n.scoprialtri,
TipoConversione = 1,
TassoConversione = n.tassoconversione,
IndiceConversione = (float)n.conversione,
UrlNegozio = n.url,
TestoVetrina=n.testovetrina,
ListaBrand = from b in n.tBrands
where b.attivo == true
select new Brand
{
Attivo = (bool)b.attivo,
BrandId = b.BrandId,
Descrizione = b.descrizione,
Logo1 = b.logo1,
Logo2 = b.logo2,
Nome = b.nome
},
ListaTag = from t in n.tTags
select new Tag
{
Id = t.TagId,
Nome = t.tag
},
ListaCategory = from c in n.tCategories
select new Category
{
Id = c.CategoryId,
Nome = c.nome
},
ListaRegole = from r in n.tRules
select new Rules
{
RegolaId = r.RegolaId,
Attiva = (bool)r.attiva,
Conversione = (float)r.conversione,
Note = r.note,
Punti = (int)r.punti,
Shopid = (int)r.Shop_id,
TestoRegola = r.testoregola,
TipoRegola = (int)r.tiporegola,
ValoreMassimo = (decimal)r.valoremassimo,
ValoreMinimo = (decimal)r.valoreminimo
},
Tiponegozio = new TipiNegozio{ Id=n.tTipiNegozio.id, Nome=n.tTipiNegozio.tipo},
};
return negozi.ToList();
}
In questo spezzone di codice viene fatto anche il mapping tra gli oggetti del model e gli oggetti del viewmodel.public class ShopService
{
private IShopRepository _shoprepository;
public ShopService(IShopRepository shoprepository)
{
_shoprepository = shoprepository;
}
public IEnumerable<ShopViewModel> GetAll()
{
return _shoprepository.FindAll().ConvertToShopViewList();
}
(....)
}
Dove avviene la magia?
Nel progetto del sito MVC ho creato una classe BootStrapper che si occupa di assegnare ad una richiesta di un tipo astratto un tipo concreto:
public class BootStrapper
{ public static void ConfigureDependencies()
{ ObjectFactory.Initialize(x=>
{
x.AddRegistry<ControllerRegistry>();
}); }
public class ControllerRegistry : Registry
{
public ControllerRegistry()
{
ForRequestedType<ICategoryRepository>().TheDefault.Is.OfConcreteType<CategoryRepository>();
ForRequestedType<IShopRepository>().TheDefault.Is.OfConcreteType<ShopRepository>();
ForRequestedType<IPartnerRepository>().TheDefault.Is.OfConcreteType<PartnerRepository>(); }
}
}
Nell'evento Application_start:
E il gioco è fatto. Il layer dei servizi è completamente disaccoppiato dal modo con cui si accede ai dati.protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
BootStrapper.ConfigureDependencies();
ControllerBuilder.Current.SetControllerFactory(new IoCControllerFactory());
}
Nessun commento:
Posta un commento