Which class should be responsible for creating ID for entity? - c#

I'm struggling a little bit with following problem. Let's say I want to manage dependencies in my project, so my domain won't depend on any external stuff - in this problem on repository. In this example let's say my domain is in project.Domain.
To do so I declared interface for my repository in project.Domain, which I implement in project.Infrastructure. Reading DDD Red Book by Vernon I noticed, that he suggests that method for creating new ID for aggregate should be placed in repository like:
public class EntityRepository
{
public EntityId NextIdentity()
{
// create new instance of EntityId
}
}
Inside this EntityId object would be GUID but I want to explicitly model my ID, so that's why I'm not using plain GUIDs. I also know I could skip this problem completely and generate GUID on the database side, but for sake of this argument let's assume that I really want to generate it inside my application.
Right now I'm just thinking - are there any specific reasons for this method to be placed inside repository like Vernon suggests or I could implement identity creation for example inside entity itself like
public class Entity
{
public static EntityId NextIdentity()
{
// create new instance of EntityId
}
}

You could place it in the repository as Vernon says, but another idea would be to place a factory inside the constructor of your base entity that creates the identifier. In this way you have identifiers before you even interact with repositories and you could define implementation per your ID generation strategy. Repository could include a connection to something, like a web service or a database which can be costly and unavailable.
There are good strategies (especially with GUID) that allow good handling of identifiers. This also makes your application fully independent of the outside world.
This also enables you to have different identifier types throughout your application if the need arises.
For eg.
public abstract class Entity<TKey>
{
public TKey Id { get; }
protected Entity() { }
protected Entity(IIdentityFactory<TKey> identityFactory)
{
if (identityFactory == null)
throw new ArgumentNullException(nameof(identityFactory));
Id = identityFactory.CreateIdentity();
}
}

Yes, you could bypass the call to the repository and just generate the identity on the Entity. The problem, however, is that you've broken the core idea behind the repository: keeping everything related to entity storage isolated from the entity itself.
I would say keep the NextIdentity method in the respository, and still use it, even if you are only generating the GUID's client-side. The benefit is that in some future where you want to change how the identity's are being seeded, you can support that through the repository. Whereas, if you go with the approach directly on the Entity, then you would have to refactor later to support such a change.
Also, consider scenarios where you would use different repositories in such cases like testing. ie. you might want to generate two identities with the same ID and perform clash testing or "does this fail properly". Having a repository handle the generation gives you opportunity to get creative in such ways, without making completely unique test cases that don't mimic what actual production calls would occur.
TLDR; Keep it in the repository, even if your identifier can be client-side generated.

Related

How to set Id of Entity object when getting it from Repository

In Domain-Driven Design, how can I hydrate the Id property when I retrieve an entity from a repository? When I create an entity for the first time (before it is persisted), I can generate a unique ID in the entity's constructor. But when I retrieve an entity from the repository, it already has an ID. How do I set the Id property in this case? Passing the ID to the entity's constructor doesn't feel right to me, but maybe it is the correct approach?
I am not using an object-relational mapping (ORM) tool.
public interface IPersonRepository
{
Person GetById(long id);
}
public abstract class Entity
{
public long Id { get; private set; }
protected Entity()
{
Id = // Generate a unique Id with some algorithm.
}
}
public sealed class Person : Entity
{
//...
}
When I CREATE the Entity for the first time (before its persistence), I can generate a unique id in Entity's constructor...
which may not be a good idea. Non deterministic data (like time, or copies of remote mutable state) should be inputs to your domain model. In practice, you will often get away with it; but that alone doesn't make it a good idea.
The usual answer is that the repository will fetch the persisted representation of the information (a DTO, for example), and hand that off to a factory whose purpose is the construction of the entity.
So the identity of the entity becomes just another piece of information passed from the repository to the factory.
Now, "factory" here is just another life cycle pattern; and it can take many different forms, including the form of constructor. In which case, the identifier would normally just be passed into the entity as an argument.
Identifiers in particular can be a bit weird, because they don't normally express business semantics. It's typical of the identifier pattern that they are opaque things that really only support equality comparison. Your entities almost never look at their own identifier to figure out what to do next.
But if your entity needs a reference to its own identifier, for whatever reason, you'll normally create that reference when you initialize the object, and leave it unchanged from that point forward (in other words, the entities identifier property is an immutable reference to an immutable value).
1) Aggregate or Entity?
I think there is some confusion in your question in terms of DDD. In general you shouldn't load entities. You should load Aggregate, through Aggregate root (which is entity), all other entities for this aggregate should be loaded automatically.
From Evans DDD:
only AGGREGATE roots can be obtained directly with database queries. All other objects must be found by traversal of associations.
Martin Fowler:
Aggregates are the basic element of transfer of data storage - you request to load or save whole aggregates.
Aggregate Root
2) How to set a Id. It's a good idea to use immutable properties. public long Id { get; private set; }, lets think we are doing things correctly when we use immutable id. Now lets go ahead and found possible ways for setting Id properly.
set id from the class method. Looks confusing to set id for existing entity (aggregate root). I don't suggest to use this option.
set id from constructor. Why not? You set the Id during the creation of the entity (aggregate root). From Evans DDD:
A public constructor must follow the same rules as a FACTORY: It must be an atomic operation that satisfies all invariants of the created object.
factory. From Evans DDD:
Complex assemblies, especially of AGGREGATES, call for FACTORIES
set id during deserialisation. Is clear and simple way. I would chose this one. I would store Id and other data together (it's common practise). GetById(long id); returns Person which already had Id setted during deserialisation.

EF Context in Model Class

In our Web.API project, we use Entity Framework 6. We have a DataModel class, which contains the DatabaseContext. The DataModel is a [ThreadStatic] Singleton.
Like this:
public class DataModel
{
[ThreadStatic] private static DataModel _instance;
public static DataModel Instance => _instance ?? (_instance = new DataModel());
public DatabaseContext Context { get; private set; }
private DataModel()
{
Context = NewContext();
}
}
Now in one of our (partial) model classes, we use the context like this:
public partial class Job
{
public User CreatedByUser
{
get { return DataModel.Instance.Context.Users.FirstOrDefault(d => d.Username == CreatedBy); }
}
}
We search in another table in the database the corresponding user. This works, but in my opinion, this is not a beautiful solution. Especially if we plan to migrate our project to.NET Core and use dependency injection for the database context.
My Question is, is there a pattern, which solves the problem more elegant? Dependency injection won't work here because Entity Framework generates the model objects. Or would it be better, if we move this code from the partial class to e.g. a util class? But how can we inject there the context?
You generally want to avoid requiring your models to have awareness of their creation and usage context since that knowledge should be top down and not bottom up. Among other reasons, you'll run into design issues like you are experiencing now. You can try to design your way around it at the application level with extension methods, an inversion of control framework, utility methods, pocos, etc, but at the end of the day you are trying to solve a problem that only exists because your underlying database schema is inadequately designed for your intended usage.
For example, your Job table has a reference to the username of the user that created it. Why? It might be possible for usernames to change and any time you want additional critical properties of that user you will need to perform a secondary lookup (like you're doing in your partial class). If you instead have the Job table maintain a foreign key to the User table, you can just use a navigation property on the C# side to get the full user object as long as the appropriate related entities are included in the query. You wouldn't even need the partial class and your database schema would become more maintainable as an added bonus.
Sometimes it's best to simplify the database design to simplify the code.

Entity Framework classes vs. POCO

I have a general difference of opinion on an architectural design and even though stackoverflow should not be used to ask for opinions I would like to ask for pros and cons of both approaches that I will describe below:
Details:
- C# application
- SQL Server database
- Using Entity Framework
- And we need to decide what objects we are going to use to store our information and use all throughout the application
Scenario 1:
We will use the Entity Framework entities to pass all around through our application, for example the object should be used to store all information, we pass it around to the BL and eventually our WepApi will take this entity and return the value. No DTOs nor POCOs.
If the database schema changes, we update the entity and modify in all classes where it is used.
Scenario 2:
We create an intermediate class - call it a DTO or call it a POCO - to hold all information that is required by the application. There is an intermediate step of taking the information stored in the entity and populated into the POCO but we keep all EF code within the data access and not across all layers.
What are the pros and cons of each one?
I would use intermediate classes, i.e. POCO instead of EF entities.
The only advantage I see to directly use EF entities is that it's less code to write...
Advantages to use POCO instead:
You only expose the data your application actually needs
Basically, say you have some GetUsers business method. If you just want the list of users to populate a grid (i.e. you need their ID, name, first name for example), you could just write something like that:
public IEnumerable<SimpleUser> GetUsers()
{
return this.DbContext
.Users
.Select(z => new SimpleUser
{
ID = z.ID,
Name = z.Name,
FirstName = z.FirstName
})
.ToList();
}
It is crystal clear what your method actually returns.
Now imagine instead, it returned a full User entity with all the navigation properties and internal stuff you do not want to expose (such as the Password field)...
It really simplify the job of the person that consumes your services
It's even more obvious for Create like business methods. You certainly don't want to use a User entity as parameter, it would be awfully complicated for the consumers of your service to know what properties are actually required...
Imagine the following entity:
public class User
{
public long ID { get; set; }
public string Name { get; set; }
public string FirstName { get; set; }
public string Password { get; set; }
public bool IsDeleted { get; set; }
public bool IsActive { get; set; }
public virtual ICollection<Profile> Profiles { get; set; }
public virtual ICollection<UserEvent> Events { get; set; }
}
Which properties are required for you to consume the void Create(User entity); method?
ID: dunno, maybe it's generated maybe it's not
Name/FirstName: well those should be set
Password: is that a plain-text password, an hashed version? what is it?
IsDeleted/IsActive: should I activate the user myself? Is is done by the business method?
Profiles: hum... how do I affect a profile to a user?
Events: the hell is that??
It forces you to not use lazy loading
Yes, I hate this feature for multiple reasons. Some of them are:
extremely hard to use efficiently. I've seen too much times code that produces thousands of SQL request because the developers didn't know how to properly use lazy loading
extremely hard to manage exceptions. By allowing SQL requests to be executed at any time (i.e. when you lazy load), you delegate the role of managing database exceptions to the upper layer, i.e. the business layer or even the application. A bad habit.
Using POCO forces you to eager-load your entities, much better IMO.
About AutoMapper
AutoMapper is a tool that allows you to automagically convert Entities to POCOs and vice et versa. I do not like it either. See https://stackoverflow.com/a/32459232/870604
I have a counter-question: Why not both?
Consider any arbitrary MVC application. In the model and controller layer you'll generally want to use the EF objects. If you defined them using Code First, you've essentially defined how they are used in your application first and then designed your persistence layer to accurately save the changes you need in your application.
Now consider serving these objects to the View layer. The views may or may not reflect your objects, or an aggregation of your working objects. This often leads to POCOS/DTO's that captures whatever is needed in the view. Another scenario is when you want to publish objects in a web service. Many frameworks provide easy serialization on poco classes in which case you typically either need to 1) annotate your EF classes or 2) make DTO's.
Also be aware that any lazy loading you may have on your EF classes is lost when you use POCOS or if you close your context.

Accessing HttpContext and User Identity from data layer

I need to implement AddedBy/ChangedBy type fields on my Base Entity that all other entities inherit from ( Fluent Nhibernate ).
Accessing HttpContext.User.Identity from within my Repository/Data layer is probably not a good idea.. or is it ?
What's the best way to grab my user ( current identity ) information to record who the records were added or changed by ?
Re-factoring the entire application to include user information in repository calls would be silly. I'm sure there is a better, more generic way.
Access the HttpContext from the Data Layer makes the life harder, specially if you use Unit Tests. The solution is to create a service to provide application wide user information, something like:
public interface ICurrentUserService {
string UserName {get;}
string UserId {get;}
string HostIP {get;}
// etc.
}
Then you can implement the concrete service and inject it using your
preferred IoC container.
public class CurrentWebUserService : ICurrentUserService {
// implement interface members
public CurrentWebUserService(HttpContext context) { ... }
public string UserName { get { ... } }
// etc.
}
// maybe you want a stub service to inject while unit testing.
public class CurrentUserServiceStub : ICurrentUserService {
}
// data layer
public class MyDaoService {
public DaoService(ICurrentUserService currentUser) { ... }
}
You're correct. Referencing your HttpContext.User.Identity class from within your repository is not a good idea. The HttpContext is a UI concern and as such, should go no further than the UI layer.
What you should be doing is harnessing an IoC container (such as StructureMap) to inject your dependency (HttpContext.User.Identity) details into your repository, or any other layer such as the service layer via dependency injection.
For an example of how this can be setup (in this instance it's the session object) see the latter part of this answer.
HttpContext.Current is a static member that you can access anywhere in the application.
https://msdn.microsoft.com/en-us/library/system.web.httpcontext.current%28v=vs.110%29.aspx
Obviously there are problems, such as if you don't HAVE an HttpContext when the code is called.
So HttpContext.Current.User should work for you. I wouldn't recommend it, because your underlying data access code is now depending on stuff that should be kept to your display or controller logic, etc. Also, this assumes that your data access is in the web application itself and not part of, say, an external library.
Personally, I'd just pass in the salient details, like user ID and access time, as part of the add and modify database calls. Make an "AuditTrail" class or something. That would let you reuse that data access code (always a good thing) in another project without having to pull out all the HttpContext stuff.
The AddedBy/ChangedBy field is potentially important in any data backend. You may even want to have AccessedBy for logging purposes. Therefore, you would want to think that the user information is a central part of your data. It is also possible that you may want other details such as the client's IP address logged for security reasons. Probably a good idea to have the entire context rippled down to the data layer so that you have the flexibility to capture and save the client information.
I have used a factory to get the correct repo with or without a "CurrentUser" since sometimes you need to know who the user is and sometimes you don't.
//I have a current user that I got from the Identity
var repo = RepoFactory.GetRepo<Users>(currentUserId);
//I don't have a current user
var repo = RepoFactory.GetRepo<Users>()
This way you can pull the Identity from the HttpContext and pass only details you need to the repo.
HttpContext.User.Identity is of System.Security.Principal.IIdentity type. Don't mess it up with Microsoft.AspNet.Identity library (NuGet package) which is actually pointed by asp.net-identity tag in your question.
Identity lib consists of common part and its ORM implementation. Typically it is for Entity Framework. But if you're going to use Microsoft.AspNet.Identity package in the way you describe with NHibernate, then you most likely will need this package.
I didn't use it, but I used EF implementation. See this answer how to inherit of predefined IdentityDbContext<T> where T is your User class. I guess, NH has similar fluent configuration. Then you can link any of entities in your DbContext to AppUser

How to add custom methods with database logic

I created an application with this architecture:
MyProject.Model: Contains POCO. Example:
public class Car
{
public int Id { get; set; }
public string Name { get; set; }
}
MyProject.Repositories: Contains repositories and UnitOfWork
public class UnitOfWork
{
// ...
public Repository<Car> Cars { get; set; }
// ...
}
public class Repository<T>
{
// ...
// Add / Update / Delete ...
// ...
}
MyProject.Web: ASP.Net MVC application
Now I want to find a way to interact with data by using methods. For example in MyProject.Model.Car I want to add a method that will get data with non-navigation properties, a method named `GetSimilarCars()'. The problem is that the repository cannot interact with other repositories and thus cannot perform operations on the database.
I don't really know how to do this in a simple manner and what is the best place in my architecture to put this.
Another example could be UserGroup.Deactivate(), this method would deactivate each user and send them a notification by email. Of course I can put this method in the Web application Controller but I think this is no the place to put such code that could be called in many places in the application.
Note: I am using Entity Framework.
Any suggestion on how to implement such operations?
This type of stuff goes into your DAL (essentially your unit of work and repository, in this limited scenario). However, this is a pattern that bit me when I first starting working with MVC. Entity Framework already implements these patterns; your DbContext is your unit of work and your DbSet is your repository. All creating another layer on top of this does is add complexity. I personally ended up going with a service pattern instead, which merely sits on top of EF and allows me to do things like someService.GetAllFoo(). That way, the use of Entity Framework is abstracted away (I can switch out the DAL at any time. I can even remove the database completely and go with an API instead, without having to change any code in the rest of my application.) but I'm also not just reinventing the wheel.
In a service pattern, you're specifically only providing endpoints for the things you need, so it's a perfect candidate for things like GetSimilarCars, as you simply just add another method to the service to encapsulate the logic for that.
I would assume that your Business Layer (BL) would be communicating with your Data Access Layer (DAL). That way from your BL you could reach out to different repositories in DAL. That would solve your problem of repositories not being able to share data (that data would be shared through BL).
See here: N-tier architecture w/ EF and MVC
I did not quite get you question but this is how you assign the values. And add it into a collection
public class Repository<T>
{
List<car> _lstCar=new List<car>();
//Add
car cobj=new car();
cobj.Id="1234";
cobj.Name="Mercedes";
_lstCar.Add(cobj);
}

Categories