I have a typical application with Controllers, Services, Repositories. So, there are 2 projects:
ASP.NET Core WebAPI with controllers
Core with all business logic
The WebAPI should know only about services from Core. In the Core I have public classes (services) that returns DTOs, but these services depends on DbContext that I want to mark as internal. Of course I can't
Error CS0051 Inconsistent accessibility: parameter type
'DevicesDbContext' is less accessible than method
'DeviceService.DeviceService(DevicesDbContext, IMapper)'
I'm using EF Core and instead of own Repositories I use DbContext. I have entity model that I have to use only in Core project. Could you please advice how can I achieve that?
For example my model is:
internal class Device
{
public int Id {get;set;}
}
DbContext:
internal class DevicesDbContext : DbContext
{
public DbSet<Device> Devices {get;set;}
}
Service:
public class DeviceService : IDeviceService
{
public DeviceService(DevicesDbContext dbContext, IMapper mapper)
{
}
..
}
I got that error in constructor of DeviceService. It is not a duplicate because I know what that error mean and how to fix that. Here I asked about design or architecture of this approach because I need to avoid of using models and dbcontext in WebAPI directly
If you don't want to use Repositories to guard data access (which generally still return Entities, not DTOs, so Entities need to be public) then the real question is:
"Why do you want to avoid using the DbContext & Entities in your Web API?"
Entity Framework is a framework. It's purpose is to facilitate data access to make your code easier to write and easier to understand. Just as you chose to use the .Net framework and leverage things like Linq, Generics, etc. by chossing EF you should seek to leverage everything it offers.
If you absolutely must keep the context and entities out of the API assembly references, or want to centralize business logic involving entities between a Web API and another set of MVC controllers then you're looking at building an anemic API. In this case:
Services.DLL -- References DbContext, entities..
public interface ISomethingService
{
IEnumerable<SomeDto> GetSome(/*params*/);
}
public class SomethingService : ISomethingService
{
public SomethingService(SomeDbContext context)
{ // Init stuff.
}
IEnumerable<SomeDto> ISomethingService.GetSome()
{
// Get some stuff and return DTOs.
}
}
Web API DLL -- Only references DTOs.
public class SomeAPI : ISomethingService
{
private ISomethingService Service { get; set; }
public SomeAPI(ISomethingService service)
{
Service = service;
}
public IEnumerable<SomeDto> GetSome()
{
return Service.GetSome();
}
}
The API is anemic in that it just passes requests through to a common service and forwards the response. The API doesn't need to implement the same interface, it can simply accept a reference to the service and consume it, passing through whatever parameters to get the DTOs that it will pass back.
The downside of this approach is that to modify the service you're flipping between the API and the Services layer vs. just working within the API. I don't favor using approaches like this because APIs and such often need to consider details like filtering, paging, etc. so I want to leverage the excellent LINQ capabilities that EF offers. I also leverage EF's IQueryable support heavily to keep my data access layer simple and compact, letting consuming services decide how to fetch the detail they need. Masking this with an extra service boundary adds complexity and inefficiencies as it either results in complex code, lots of very similar functions, and/or wasted memory/processing to return data that is not needed.
Related
Overview
I am making a .net-core web API with simple CRUD operations.
I have made the GET methods and got them up and running, however when I try to implement the Create method using dbContext.Add(myItem) I am not able to use dbContext.SaveChanges() afterwards.
My current work is available at:
https://github.com/petermefrandsen/TKD-theory-API
So far
I have tried adding a overwriting method to my database context.
Additionally I have tried adding the entity framework reference to the project.
As I do use interfaces for loose coupling I am at a loss when I comes to comparing with tutorials and other peoples similar problems. (read I am fairly new to c#).
Code
Controller:
[Route("dan/")]
[HttpPost]
public ActionResult<DanTheoryItem> PostDanTheoryItem(DanTheoryItem danTheoryItem)
{
_context.PostDanTheoryItem(danTheoryItem);
return new ActionResult<DanTheoryItem>(danTheoryItem);
}
IContext:
DanTheoryItem PostDanTheoryItem(DanTheoryItem danTheoryItem);
Context:
public DanTheoryItem PostDanTheoryItem(DanTheoryItem danTheoryItem)
{
var theoryItem = new DbDanTheoryItems
{
Id = danTheoryItem.Id,
KoreanTheoryItemId = danTheoryItem.KoreanTheoryItemId,
MainCategory = danTheoryItem.MainCategory,
SubCategory = danTheoryItem.SubCategory,
SubToSubCategory = danTheoryItem.SubToSubCategory,
NameLatin = danTheoryItem.NameLatin,
NamePhonetic = danTheoryItem.NamePhonetic,
NameAudio = danTheoryItem.NameAudio
};
_dbContext.DanTheoryItems.Add(theoryItem);
//_dbContext.SaveChanges();
return danTheoryItem;
}
Desired result
I'd like to have the controller call the context methods that will write the desired data to the database.
Your interface doesn't contain a SaveChanges method. Since you are using dependency injection only the methods in your interface will be available to your controller.
If you inherit from System.Data.Entity.IDbContext class in your custom interface, the method will be exposed to you in your controller.
Instantiating an instance of your DbLokisaurTKDTheoryAppContext class in your controller will expose the SaveChanges method as well.
It's hard to say exactly because you've neglected to post certain key portions of your code. However, my best guess is that you "context" is being provided IDbContext (of your own creating), instead of DbContext, and your interface doesn't define a SaveChanges method.
Honestly, just get rid of IDbContext. The point of an interface is to define a contract between multiple implementations. Here, there can be only one implementation: DbContext, and DbContext isn't even aware of this interface. Just inject your derived DbContext directly.
Using an interface isn't a magic wand. You have a hard dependency on Entity Framework here, so interface or not, you're tightly coupled. That's not necessary a bad thing though. EF is serving as your data layer, and this application is data driven; it's going to be tightly coupled to the data layer no matter what.
The API itself serves as your abstraction. Other layers will presumably just use the API, so no further abstraction is necessary, and in fact just adds more maintenance concern with no added benefit.
I'm trying to build my first (Rest?) WCF service on .NET with entity framework 6 following Repository pattern.
So it is supposed that I have to expose only simple object from the service, not the entire EF classes, right?
So I build a simple Model Like this, that represent some field from a database table:
[DataContract]
public class FormasPagoModel
{
[DataMember]
public int ID { get; set; }
[DataMember]
public string FormaPago { get; set; }
}
This is the data type returned by my WCF service method. So I whant a method GetbyID on my service. To do so, i create an interface:
public interface IRepository<T> where T:class
{
T GetEntityByID(int Key);
}
and a Repository abstract class:
public abstract class Repository<T> : IRepository<T> where T : class
{
protected readonly OhmioNETEntities context = new OhmioNETEntities();
public T GetEntityByID(int Key)
{
return context.Set<T>().Find(Key);
}
}
and a concrete implementation (ANX_FormasPago is my EF Class that is linked to a database table):
public class FormasPagoRep : Repository<ANX_FormasPago>
{
}
Finally my WCF Service class
public class WCFService
{
public FormasPagoModel FormasPago_GetbyID(int Key)
{
ANX_FormasPago EFEntity = new FormasPagoRep().GetEntityByID(Key);
return new FormasPagoModel
{
ID = EFEntity.ID_FormaPago,
FormaPago = EFEntity.FormaPago,
};
}
}
As you can see, internally I get an EF class of type ANX_FormasPago and transform it to FormasPagoModel. Of course if I need for instance FormasPago_Save, i need to write the exact oposite code that is transform my Model(FormasPagoModel) to EF class(ANX_FormasPago)
With this code, I end up having, for each database table:
A) An EF class.
B) A Simplified Model class.
C) A concrete Repository.
D) A WCF Service method for each method.
So, I'm I in the right path here? Or am i just complicating things up.
I think, you're almost there. In my opinion you are actually missing one layer (Business logic). It's not the responsibility of your WCF service to get data from repository and convert it to a different type. The reason is that in many cases the creation of the final model object can be much more complex. I wouldn't like to clutter the WCF service with that.
Ideally the architecture would look like that:
WCF --> Business Logic --> Repository --> Entity Framework
Every layer can only talk to the layer directly on it's right.
Repository returns filtered EF entities
Business processes them (can use multiple repositories, perform calculations and other stuff)
Business returns simple DTO objects (Business should not reference WCF)
WCF grabs DTOs and maps them to WCF models (I'd use AutoMApper for that btw). This mapping is necessary as Business doesn't reference WCF components (DataContract and DataMember attributes are not accessible in Business).
WFC releases models to the web
Also I wouldn't bother to have an abstract / base / generic repository. Sooner or later you'll end up having some ugly workarounds to handle not compatible entities (Refused bequest problem).
Ultimately you'll end up having even more classes than you proposes, but each of them will have single responsibility. They'll be simpler, easier to test and more reusable (e.g. you can replace WCF layer and use WPF or MVC instead without touching different layers).
I would like to ask some help regarding Dependency Injection and, I think, architectural approach.
So, I have an ORM layer implemented by EF6 where the objects are described and Ef does what its business, etc. I created a custom library over it, called DatabaseApi and it is mentioned in the title as "Api", where I query the data and map it to datacontract objects. I do it for pure testing purposes. I would like to have the different libraries in my application testable.
I started to implement the code where I inject the DbContext but I don't know how to deal with the usings in this case.
I went through a few blogposts and articles about mocking and EF, especially this one but it is rather about testing EF itself and not about how to decouple it from other libraries. On the other hand, I assume my search keywords were not proper.
Do you know any good and usable tutorials and articles about how to decouple entity framework from other libraries?
Thanks in advance!
Examples:
I created an empty interface in order to the DbContext can be injectable. It is implemented by the databaseContext.
public interface IDatabase
{
}
public class DatabaseModelContext : DbContext, IDatabase{
public DbSet<TableOne> TableOne { get; set; }
public DbSet<TableTwo> TableTwo { get; set; }
}
In the custom Api library constructor I put together a code to resolve the interface by Unity. I don't know whether it is working or not. I haven't executed yet.
public partial class DatabaseApi : IDatabaseApi {
private readonly IDatabase iDatabase;
private readonly UnityContainer unityContainer;
public DatabaseApi()
{
this.unityContainer = new UnityContainer();
this.unityContainer.RegisterType<IDatabase, DatabaseModelContext>();
this.iDiLibDatabase = this.unityContainer.Resolve<IDiLibDatabase>();
}
}
And here is the problem. Due to the injection I'll have and interface but there are the usings which are important to manage the resource as far as I know. How to do it?
public partial class DatabaseApi : IDatabaseApi
{
public List<SomeDataContract> GetMainStructure()
{
var result = new List<SomeDataContract>();
//this is the old implementation
using (var database = new DatabaseModelContext())
{
//some data manipulation magic... :)
}
return result;
}
If you're okay using linq to objects as a core element of your domain access layer then exposing an IQueryable for access to the entities would work...
public interface IRepository<TEntity>
{
IQueryable<TEntity> AllEntities { get; }
}
With that, you can do your Where, Select, etc. without hard wiring directly to EF. Behind the scenes the IRepository implementations would deal with the EF portions, database connectivity, etc. There's no avoiding coupling the to EF at the data access layer. But you can keep it constrained to just that layer using something like you've started. Just make sure the database contexts used by your IRepository objects are the only objects working with EF.
Put another way: Don't have your IDatabase return entities. Just have it deal with the connections, and you should create another layer for domain object access which takes in an IDatabase. In the example I gave, somehow the IRepository implementations would take in an instance of IDatabase.
So, the solution is using Autofac DI framework. I found interesting questions and answers and two really helpful tutorials. Links below:
How do you reconcile IDisposable and IoC?
Dependency Injection with Autofac
Generic Repository and Unit of Work Pattern, Entity Framework, Unit Testing, Autofac IoC Container and ASP.NET MVC
Autofac homepage
I have a design problem with my poject that I don't know how to fix, I have a DAL Layer which holds Repositories and a Service Layer which holds "Processors". The role of processors is to provide access to DAL data and perform some validation and formatting logic.
My domain objects all have a reference to at least one object from the Service Layer (to retrieve the values of their properties from the repositories). However I face two cyclical dependencies. The first "cyclical dependency" comes from my design since I want my DAL to return domain objects - I mean that it is conceptual - and the second comes from my code.
A domain object is always dependent of at least one Service Object
The domain object retrieves his properties from the repositories by calling methods on the service
The methods of the service call the DAL
However - and there is the problem - when the DAL has finished his job, he has to return domain objects. But to create these objects he has to inject the required Service Object dependencies (As these dependencies are required by domain objects).
Therefore, my DAL Repositories have dependencies on Service Object.
And this results in a very clear cyclical dependency. I am confused about how I should handle this situation. Lastly I was thinking about letting my DAL return DTOs but it doesn't seem to be compatible with the onion architecture. Because the DTOs are defined in the Infrastructure, but the Core and the Service Layer should not know about Infrastucture.
Also, I'm not excited about changing the return types of all the methods of my repositories since I have hundreds of lines of code...
I would appreciate any kind of help, thanks !
UPDATE
Here is my code to make the situation more clear :
My Object (In the Core):
public class MyComplexClass1
{
MyComplexClass1 Property1 {get; set;}
MyComplexClass2 Property2 {get; set;}
private readonly IService MyService {get; set;}
public MyComplexClass1(IService MyService)
{
this.MyService = MyService;
this.Property1 = MyService.GetMyComplexClassList1();
.....
}
This is my Service Interface (In the Core)
public interface IService
{
MyComplexClass1 GetMyComplexClassList1();
...
}
This my Repository Interface (In the Core)
public interface IRepoComplexClass1
{
MyComplexClass1 GetMyComplexClassObject()
...
}
Now the Service Layer implements IService, and the DAL Layer Implements IRepoComplexClass1.
But my point is that in my repo, I need to construct my Domain Object
This is the Infrascruture Layer
using Core;
public Repo : IRepoComplexClass1
{
MyComplexClass1 GetMyComplexClassList1()
{
//Retrieve all the stuff...
//... And now it's time to convert the DTOs to Domain Objects
//I need to write
//DomainObject.Property1 = new MyComplexClass1(ID, Service);
//So my Repository has a dependency with my service and my service has a dependency with my repository, (Because my Service Methods, make use of the Repository). Then, Ninject is completely messed up.
}
I hope it's clearer now.
First of all, typically architectural guidance like the Onion Architecture and Domain Driven Design (DDD) do not fit all cases when designing a system. In fact, using these techniques is discouraged unless the domain has significant complexity to warrant the cost. So, the domain you are modelling is complex enough that it will not fit into a more simple pattern.
IMHO, both the Onion Architecture and DDD try to achieve the same thing. Namely, the ability to have a programmable (and perhaps easily portable) domain for complex logic that is devoid of all other concerns. That is why in Onion, for example, application, infrastructure, configuration and persistence concerns are at the edges.
So, in summary, the domain is just code. It can then utilize those cool design patterns to solve the complex problems at hand without worrying about anything else.
I really like the Onion articles because the picture of concentric barriers is different to the idea of a layered architecture.
In a layered architecture, it is easy to think vertically, up and down, through the layers. For example, you have a service on top which speaks the outside world (through DTOs or ViewModels), then the service calls the business logic, finally, the business logic calls down to some persistence layer to keep the state of the system.
However, the Onion Architecture describes a different way to think about it. You may still have a service at the top, but this is an application service. For example, a Controller in ASP.NET MVC knows about HTTP, application configuration settings and security sessions. But the job of the controller isn't just to defer work to lower (smarter) layers. The job is to as quickly as possible map from the application side to the domain side. So simply speaking, the Controller calls into the domain asking for a piece of complex logic to be executed, gets the result back, and then persists. The Controller is the glue that is holding things together (not the domain).
So, the domain is the centre of the business domain. And nothing else.
This is why some complain about ORM tools that need attributes on the domain entities. We want our domain completely clean of all concerns other than the problem at hand. So, plain old objects.
So, the domain does not speak directly to application services or repositories. In fact, nothing that the domain calls speaks to these things. The domain is the core, and therefore, the end of the execution stack.
So, for a very simple code example (adapted from the OP):
Repository:
// it is only infrastructure if it doesn't know about specific types directly
public Repository<T>
{
public T Find(int id)
{
// resolve the entity
return default(T);
}
}
Domain Entity:
public class MyComplexClass1
{
MyComplexClass1 Property1 {get; } // requred because cannot be set from outside
MyComplexClass2 Property2 {get; set;}
private readonly IService MyService {get; set;}
// no dependency injection frameworks!
public MyComplexClass1(MyComplexClass1 property1)
{
// actually using the constructor to define the required properties
// MyComplexClass1 is required and MyComplexClass2 is optional
this.Property1 = property1;
.....
}
public ComplexCalculationResult CrazyComplexCalculation(MyComplexClass3 complexity)
{
var theAnswer = 42;
return new ComplexCalculationResult(theAnswer);
}
}
Controller (Application Service):
public class TheController : Controller
{
private readonly IRepository<MyComplexClass1> complexClassRepository;
private readonly IRepository<ComplexResult> complexResultRepository;
// this can use IoC if needed, no probs
public TheController(IRepository<MyComplexClass1> complexClassRepository, IRepository<ComplexResult> complexResultRepository)
{
this.complexClassRepository = complexClassRepository;
this.complexResultRepository = complexResultRepository;
}
// I know about HTTP
public void Post(int id, int value)
{
var entity = this.complexClassRepository.Find(id);
var complex3 = new MyComplexClass3(value);
var result = entity.CrazyComplexCalculation(complex3);
this.complexResultRepository.Save(result);
}
}
Now, very quickly you will be thinking, "Woah, that Controller is doing too much". For example, how about if we need 50 values to construct MyComplexClass3. This is where the Onion Architecture is brilliant. There is a design pattern for that called Factory or Builder and without the constraints of application concerns or persistence concerns, you can implement it easily. So, you refactor into the domain these patterns (and they become your domain services).
In summary, nothing the domain calls knows about application or persistence concerns. It is the end, the core of the system.
Hope this makes sense, I wrote a little bit more than I intended. :)
We are using the repository pattern in our ASP.NET MVC 3 application. This means that, although we use EF 4.1 Code First to access the data in the backend, all MVC controllers do that via a generic repository class rather than directly over the DbContext subclass.
Simplified code snippet:
public class MyEntityContext : DbContext, IMyEntityContext
{
public IDbSet MyEntities { get; set; }
...
}
public class MyEntityRepository : IMyEntityRepository
{
private IMyEntityContext _context;
public IQueryable<MyEntity> MyEntities
{
return _context.MyEntities;
}
...
}
public class MyEntityController : Controller
{
private MyEntityRepository _repository;
...
}
We use interfaces and dependency injection for every dependency. It works fine. Looks nice, doesn't it? But now for the caveat:
We also provide a WCF Data Service (CTP supporting Code First) to access the entities. We want to use the repository in that service, too. But this seems tricky. When using the MyEntityContext directly, the service looks like this:
public class MyEntityService : DataService<MyEntityContext>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("MyEntities", EntitySetRights.All);
}
}
But when I try to replace the MyEntityContext by the repository, there are two issues:
The type specified for the generic DataService<..> needs to be a class with a default constructor, which breaks the pretty design-by-contract and dependency injection design.
It even seems that the type provided has to be a DbContext class: I tried and used the MyEntityRepository instead, but failed (see details).
I seem lost... Can anyone bring me back on the proper track?
Details:
My first go was:
public class MyEntityService : DataService<MyEntityRepository>
{
...
However, when calling the service, it fails with the following error message:
The server encountered an error processing the request. The exception message is 'On data context type 'MyEntityRepository', there is a top IQueryable property 'MyEntities' whose element type is not an entity type. Make sure that the IQueryable property is of entity type or specify the IgnoreProperties attribute on the data context type to ignore this property.'.
I tried the following steps to fix this, but did not get rid of this error message:
Adding a [DataServiceKey("MyEntityId")] to MyEntity, where MyEntityId is the correct key property of the entity.
Replacing the type of Repository.MyEntities by IDbSet instead of IQueryable.
BTW: The following posts are not duplicates:
WCF Repository Service pattern with entity framework
Service Layer/Repository Pattern
Best way to implement Repository Pattern?
webservices with repository pattern in c# and WCF?
WCF Service design pattern
Why do you want to use repository? You have context so use it. Don't create onion architecture just because you want to use pattern. WCF data service already handles everything you need itself. No sorry, it sometimes offers even more (for example interceptors).
By using custom repository you are moving to reflection provider data source. If you also plan to modify your entities through WCF data service that is also against your repository because reflection provider is read only unless it also implements IUpdateable. Check also rules for reflection provider.
Btw. WCF Data Services in .NET 4 doesn't support DbContext directly (that support is only in CTPs of upcoming version) but you there is workaround for that. The link is for old CTP. In current version there is not UnderlyingContext property but you can use IObjectContextAdapter to get ObjectContext.
As you can also see in last link type provided to the service doesn't need to have default constructor - it is up to you what constructor you use when creating data source. If you need dependency injection you will probably have to check the way how to inject directly to the service itself (for example here for Unity and plain WCF) and use injected data in CreateDataSource.
Here's how to make a WCF Data Service with whatever pattern you're using, even none at all.
Getting Started With OData Part 2: Building an OData Services from Any Data Source
Just make sure your entity, poco, model or whatever has a property public int ID , or has this class annotation provided by the System.Data.Services assembly in the System.Data.Services namespace:
[DataServiceKey("TheNameOfYourPrimaryKeyProperty")]
This will make it recognizable as an entity type by the WCF Data Service.
As others have pointed out though, just make sure that adding yet another layer in your stack is a good decision.