Sto cercando di implementare il modello UoW / Repository di base con ASP.NET/Entity Framework Core e ho riscontrato un comportamento molto problematico.
La mia soluzione consiste di 4 progetti in totale.
Progetto .DAL , dove sono definite le mie classi di entità e dove è definito il mio DbContext:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
public class ApplicationDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
Progetto .Facade , dove sono definiti IUnitOfWork e IProductRepository:
public interface IUnitOfWork
{
IProductRepository Products { get; }
}
public interface IProductRepository
{
string GetName(int id);
}
Progetto .Facade.EF , dove my Face è implementato con EF:
public class UnitOfWork : IUnitOfWork
{
private ApplicationDbContext _context;
public IProductRepository Products { get; private set; }
internal ApplicationDbContext Context { get { return _context; } }
public UnitOfWork()
{
_context = new ApplicationDbContext();
Products = new ProductRepository(this);
}
}
public class ProductRepository : IProductRepository
{
private ApplicationDbContext _context;
public ProductRepository(UnitOfWork uow)
{
_context = uow.Context;
}
public string GetName(int id)
{
return _context.Products
.Where(x => x.Id == id)
.Select(x => x.Name)
.FirstOrDefault();
}
}
Progetto .DemoApp dove dovrebbe essere il mio codice applicativo. Questo progetto dovrebbe conoscere solo UnitOfWork e UserRepository e non la classe ApplicationDbContext.
Riferimenti .DAL Entity Framework 6.1.3.
.Facade non fa riferimento a nulla.
Riferimenti .Facade.EF. Progetto DAL, progetto .Facade e Entity Framework 6.1.3.
.DemoApp riferimenti Facade e Facade.EF ma NOT Entity Framework 6.1.3. Progetto NOR .DAL. Anche se gli assembly EF vengono aggiunti alla mia cartella bin su build, EF non viene referenziato direttamente da questo progetto.
Con .NET Framework 4.6.x. , Se provo a tentare di codificare ApplicationDbContext in DemoApp, mi dice che la classe non è definita e non mi fornisce alcun utilizzo da aggiungere quale comportamento previsto.
Se provo a fare lo stesso con .NET Core 1.0 RC2 (utilizzando Entity Framework Core), ApplicationDbContext è accessibile da .DemoApp senza aggiungere riferimenti diretti al progetto .DAL che distrugge completamente il mio tentativo di nascondere i dettagli di implementazione.
Il progetto .DAL non è referenziato direttamente dal progetto .DemoApp: perché posso vedere le lezioni da lì?
È questo comportamento previsto? C'è un modo per fare in modo che i progetti .NET Core abbiano lo stesso comportamento dei progetti .NET Framework 4.6.x?
Ho lottato per mesi e finalmente ho trovato un modo per disabilitare i riferimenti transitivi dei progetti in Core.
Nel file .csproj per .Facade.EF, è possibile aggiungere PrivateAssets="All"
a ProjectReference a .DAL:
<ItemGroup>
<ProjectReference Include="..\.DAL\.DAL.csproj" PrivateAssets="All" />
</ItemGroup>
Con questa impostazione, i progetti che fanno riferimento a .Facade.EF non fanno più riferimento anche a .DAL.
In termini più astratti, se vuoi che A faccia riferimento a B e B per fare riferimento a C, ma non vuoi che A faccia riferimento a C, aggiungi questo:
In B.csproj
<ItemGroup>
<ProjectReference Include="..\C\C.csproj" PrivateAssets="All" />
</ItemGroup>
Questo è il comportamento previsto. Si chiama meta-pacchetti e viene utilizzato ad esempio per il pacchetto NETStandard.Library
per includere tutte le librerie della libreria della classe base. Non penso che ci sia un modo per nasconderli.