I recently did some work on adjusting the Dapper to my needs and it works quite good but I noticed I have certain code that repeates and I want to minify that as much as possible. Current way this works is:
I have a base DAL class that does some basic operation such as Save, Delete, Get, etc. Along with that it has a property named IsNew that...well...you've guessed determines if it's new or existing entity.
public class DalBase
{
public bool IsNew
{
get;
private set;
}
public static T New<T>()
{
// removed for clarity
}
public void Get<T>(params object[] parameters)
{
// removed for clarity
}
public void Save()
{
// removed for clarity
}
public void Delete()
{
// removed for clarity
}
}
If I want to define my entity, lets say person, I would do it this way:
public partial class Person
{
private PersonDal m_dal;
public bool IsNew
{
get
{
return m_dal.IsNew;
}
}
public int? PersonID
{
get
{
return m_dal.PersonID;
}
}
public string PersonName
{
get
{
return m_dal.PersonName;
}
set
{
m_dal.PersonName = value;
}
}
public string PersonSurname
{
get
{
return m_dal.PersonSurname;
}
set
{
m_dal.PersonSurname = value;
}
}
public DateTime? PersonDateOfBirth
{
get
{
return m_dal.PersonDateOfBirth;
}
set
{
m_dal.PersonDateOfBirth = value;
}
}
private Person()
{
m_dal = DalBase.New<PersonDal>();
}
public static Person New()
{
return new Person();
}
public static Person Get(int PersonID)
{
var personDal = DalBase.Get<PersonDal>(PersonID);
if (personDal == null)
return null;
var person = new Person();
person.m_dal = personDal;
return person;
}
private class PersonDal : DalBase
{
public int? PersonID
{
get;
set;
}
public string PersonName
{
get;
set;
}
public string PersonSurname
{
get;
set;
}
public DateTime? PersonDateOfBirth
{
get;
set;
}
private PersonDal()
{
IsNew = true;
}
}
}
As you can see my DAL is contained inside the Entity class. This way I can do all sorts of things like mappings, preliminary checks before update or insert, etc. But, this is not why I copy pasted this code here :)
What I want to do is somehow eliminate IsNew from the entity because it will repeate on every entity definition and it seems a bit redundant AND more because I might be thinking of adding some columns that are common for all tables such as DateOfEdit, UserEdit, etc... As you can see it would be very handy to add it in one place and than inherit it and just keep specific columns in each entity definition.
What I tried doing by now is using generics like this:
public class EntityBase<T> where T : DalBase
{
protected T m_dal;
public bool IsNew
{
get
{
return m_dal.IsNew;
}
}
}
This would allow me to inherit base entity with specific Dal class so I can have my person entity defined as such:
public partial class Person : EntityBase<PersonDal>
The problem with this approach is that the PersonDal is private class of Person entity and as such has less accessibility than the entity itself and if I just define it as public - well it beats the whole purpose since the DAL is used only by the entity that is concerned with it!
Is there any other way that we could achieve this?
DAL has nothing to do with the entities. You mix the concepts here. Use DAL as an individual class, not as a member field/variable of your entity classes and pass the entity types to DAL.
If you have to have the DAL in your entities, use DI and pass the DAL instance in the constructor.
Or if you want to use your original approach, create a simple EF project with two entity types and check how it works.
Related
When I save the change everything looks good. CaseWorkNote entity is properly created and added to workNotes collection (property of Case entity).
When CurrentUnitOfWork calls DbContext->SaveChanges() I see that my entity is there with status Added.
In the end nothing is saved to DB.
What I miss in my code or what I'm doing wrong?
Below is my code and screenshot with tracked entity.
Model:
public class Case : FullAuditedAggregateRoot<Guid>
{
[Required]
public CaseType Type { get; set; }
[Required]
public string Subject { get; set; }
public string Descripion { get; set; }
//Aggregated entity
private HashSet<CaseWorkNote> _workNotes;
public IEnumerable<CaseWorkNote> WorkNotes => _workNotes?.ToList();
//
public CaseWorkNote AddNote(string text)
{
if (_workNotes is null)
{
_workNotes = new HashSet<CaseWorkNote>();
}
CaseWorkNote workNote = CaseWorkNote.Create(this, text);
_workNotes.Add(workNote);
return workNote;
}
}
public class CaseWorkNote : FullAuditedEntity
{
[ForeignKey("CaseId")]
[Required]
public Case Case { get; private set; }
[Required]
public string Text { get; set; }
private CaseWorkNote() : base() { }
public static CaseWorkNote Create(Case kase, string text)
{
return new CaseWorkNote()
{
Case = kase,
Text = text
};
}
}
DBcontext:
public class testDbContext : AbpZeroDbContext<Tenant, Role, User, testDbContext>
{
public DbSet<Case> Cases { get; set; }
public DbSet<CaseWorkNote> CaseWorkNotes { get; set; }
public testDbContext(DbContextOptions<testDbContext> options)
: base(options) { }
public override int SaveChanges()
{
//Here I see CaseWorkNote entity with state = "Added"
var entries = this.ChangeTracker.Entries();
foreach (var item in entries)
{
Debug.WriteLine("State: {0}, Type: {1}", item.State.ToString(), item.Entity.GetType().FullName);
}
return base.SaveChanges();
}
}
Application Service Class:
public class CaseAppService : AsyncCrudAppService<Case, CaseDto, Guid, PagedCaseResultRequestDto, CreateCaseDto, UpdateCaseDto>, ICaseAppService
{
//Removed for brevity
...
//
public async Task AddWorkNote(CreateUpdateCaseWorkNoteDto input)
{
var kase = await this.GetEntityByIdAsync(input.CaseId);
kase.AddNote(input.Text);
CurrentUnitOfWork.SaveChanges();
}
protected override async Task<Case> GetEntityByIdAsync(Guid id)
{
var kase = await Repository
.GetAllIncluding(c => c.WorkNotes)
.FirstOrDefaultAsync(c => c.Id == id);
if (kase == null)
{
throw new EntityNotFoundException(typeof(Case), id);
}
return kase;
}
public async Task<ListResultDto<CaseWorkNoteDto>> GetWorkNotes(EntityDto<Guid> entity)
{
var kase = await this.GetEntityByIdAsync(entity.Id);
return new ListResultDto<CaseWorkNoteDto>(MapToEntityDto(kase).WorkNotes.ToList());
}
}
thanks
The problem is caused by the default EF Core property access mode and ToList() call here
public IEnumerable<CaseWorkNote> WorkNotes => _workNotes?.ToList();
Not sure what type of methodology are you following, but you are violating the simple good design rule that property (and especially collection type) should not allocate on each get. Not only because it is inefficient, but also allows the "smart" client like EF Core to detect the actual type as List and try using it to add items when loading related data.
In reality with this type of implementation they are adding to a list which is discarded, in other words - nowhere. So EF Core loading related data / navigation property fixup doesn't work, which also may affect the change tracker and lead to weird behaviors.
To fix the EF Core issue, you should configure EF Core to use directly the backing field. The easiest way is to set it globally inside the OnModelCreating override:
modelBuilder.UsePropertyAccessMode(PropertyAccessMode.Field);
It also can be set per entity or per entity property, but I would suggest the above, moreover one of the expected changes in EF Core 3.0 is that Backing fields will be used by default.
Anyway, now the problem in question will be solved.
Still, it will be better to follow the good practices. The _workNotes member should be initialized with initializer or in class constructor, and property getter should return it directly. If the idea was to prevent the caller to get access to the private member by casting the result, then there are other ways to prevent that which does not clone the collection content. For instance:
//Aggregated entity
private readonly HashSet<CaseWorkNote> _workNotes = new HashSet<CaseWorkNote>();
public IEnumerable<CaseWorkNote> WorkNotes => _workNotes.Select(e => e);
//
Regardless of whether you keep your current implementation of the navigation property or not, you must let EF Core use the backing field directly.
Add foreign key property CaseId.
Also added Virtual keyword.
public class CaseWorkNote : FullAuditedEntity
{
[ForeignKey("CaseId")]
[Required]
public virtual Case Case { get; private set; }
public virtual Guid CaseId { get; private set; } /* Added */
[Required]
public virtual string Text { get; set; }
private CaseWorkNote() : base() { }
public static CaseWorkNote Create(Case kase, string text)
{
return new CaseWorkNote()
{
Case = kase,
Text = text
};
}
}
Many tables in my database have common fields which I call 'audit' fields. They fields like - UserUpdateId, UserCreateId, DateUpdated, DateCreated, DateDeleted, RowGUID, as well as a common "Comments" table etc. In the database they are used to track who did what when. Additionally via the asp.net MVC 4 views they display these attributes to the user using common display templates (popup, mouseover etc.).
Currently, I put these properties into a [Serializable()] CommonAttributesBase class. Which I then initialize in all the models that should inherit those properties. Admittedly this is a little clunky and inefficient as my CommonAttribute class makes calls to the repository and the initialization seems like more code than necessary.
I would appreciate suggestions on how to implement this in the best way.
[Serializable()]
public class CommonAttributesBase
{
#region Notes
public Boolean AllowNotes { get; set; }
[UIHint("NoteIcon")]
public NoteCollection NoteCollection
{
get
{
if (!AllowNotes) return null;
INoteRepository noteRepository = new NoteRepository();
var notes = noteRepository.FindAssociatedNotes(RowGUID);
return new NoteCollection { ParentGuid = RowGUID, Notes = notes, AuditString = AuditTrail };
}
}
#region Audit Trail related
public void SetAuditProperties(Guid rowGuid, Guid insertUserGuid, Guid updateUserGuid, Guid? deleteUserGuid, DateTime updateDate, DateTime insertDate, DateTime? deleteDate)
{
RowGUID = rowGuid;
InsertUserGUID = insertUserGuid;
UpdateUserGUID = updateUserGuid;
DeleteUserGUID = deleteUserGuid;
UpdateDate = updateDate;
InsertDate = insertDate;
DeleteDate = deleteDate;
}
[UIHint("AuditTrail")]
public string AuditTrail
{
get
{
...code to produce readable user audit strings
return auditTrail;
}
}
...additional methods
}
In another class
public partial class SomeModel
{
private CommonAttributesBase _common;
public CommonAttributesBase Common
{
get
{
if (_common == null)
{
_common = new CommonAttributesBase { AllowNotes = true, AllowAttachments = true, RowGUID = RowGUID };
_common.SetAuditProperties(RowGUID, InsertUserGUID, UpdateUserGUID, DeleteUserGUID, UpdateDate, InsertDate, DeleteDate);
}
return _common;
}
set
{
_common = value;
}
}
...rest of model
}
For me, I prefer to use different interfaces for each type (audit or note), and use decorator to retrieve those related data, instead of embedding those in the common class:
public class Note
{
//Node properties
}
public class AuditTrail
{
//Audit trail properties
}
public interface IAuditable
{
AuditTrail AuditTrail { get; set; }
}
public interface IHaveNotes
{
IList<Note> Notes { get; set; }
}
public class SomeModel : IAuditable, IHaveNotes
{
public IList<Note> Notes { get; set; }
public AuditTrail AuditTrail { get; set; }
public SomeModel()
{
Notes = new List<Note>();
}
}
public class AuditRepository : IRepository<T> where T : IAuditable
{
private IRepository<T> _decorated;
public AuditRepository(IRepository<T> decorated)
{
_decorated = decorated;
}
public T Find(int id)
{
var model = _decorated.Find(id);
model.Audit = //Access database to get audit
return model;
}
//Other methods
}
public class NoteRepository : IRepository<T> where T : IHaveNotes
{
private IRepository<T> _decorated;
public NoteRepository(IRepository<T> decorated)
{
_decorated = decorated;
}
public T Find(int id)
{
var model = _decorated.Find(id);
model.Notes = //Access database to get notes
return model;
}
//Other methods
}
Advantages is that the client will be able to choose to load audit/note or not, the logic of audit and note are also separated from the main entity repository.
What you're doing is basically composition. As others have stated, there's many ways to accomplish what you're looking for, some better than others, but each method depends on the needs of your application, of which only you can speak to.
Composition
Composition involves objects having other objects. For example, if you were going to model a car, you might have something like:
public class Car
{
public Engine Engine { get; set; }
}
public class Engine
{
public int Horsepower { get; set; }
}
The benefit to this approach is that your Car ends up with a Horsepower property via Engine, but there's no inheritance chain. In other words, your Car class is free to inherit from another class while not effecting this property or similar properties. The problems with this approach is that you have to involve a separate object, which in normally is not too troubling, but when combined when tied back to a database, you're now talking about having a foreign key to another table, which you'll have to join in order to get all the class' properties.
Entity Framework allows you to somewhat mitigate this effect by using what it calls "complex types".
[ComplexType]
public class Engine
{
...
}
The properties of complex types are mapped onto the table for the main class, so no joins are involved. However, because of this, complex types have certain limitations. Namely, they cannot contain navigation properties -- only scalar properties. Also, you need to take care to instantiate the complex type or you can run into problems. For example, any nulled navigation property is not validated by the modelbinder, but if you have a property on your complex type that is required (which results in a property on your main class' table that is non-nullable), and you save your main class while the complex type property is null, you'll get an insertion error from the database. To be safe you should always do something like:
public class Car
{
public Car()
{
Engine = new Engine();
}
}
Or,
public class Car
{
private Engine engine;
public Engine Engine
{
get
{
if (engine == null)
{
engine = new Engine();
}
return engine;
}
set { engine = value; }
}
}
Inheritance
Inheritance involves deriving your class from a base class and thereby getting all the members of that base class. It's the most straight-forward approach, but also the most limiting. This is mostly because all of the .NET family of languages only allow single inheritance. For example:
public class Flyer
{
public int WingSpan { get; set; }
}
public class Walker
{
public int NumberOfLegs { get; set; }
}
public class Swimmer
{
public bool HasFlippers { get; set; }
}
public class Duck : ????
{
...
}
That's a bit contrived, but the point is that Duck is all of a Flyer, Walker and Swimmer, but it can only inherit from one of these. You have to be careful when using inheritance in languages that only allow single inheritance to make sure that what you inherit from is the most complete base class possible, because you won't be able to easily diverge from this.
Interfaces
Using interfaces is somewhat similar to inheritance, but with the added benefit that you can implement multiple interfaces. However, the downside is that the actual implementation is not inherited. In the previous example with the duck, you could do:
public class Duck : IFlyer, IWalker, ISwimmer
However, you would be responsible for implementing all the members of those interfaces on your Duck class manually, whereas with inheritance they just come through the base class.
A neat trick with interfaces and .NET's ability to extend things is that you can do interface extensions. These won't help you with things like properties, but you can move off the implementation of some of the class' methods. For example:
public static class IFlyerExtensions
{
public static string Fly(this IFlyer flyer)
{
return "I'm flying";
}
}
Then,
var duck = new Duck();
Console.WriteLine(duck.Fly());
Just by implementing IFlyer, Duck gets a Fly method, because IFlyer was extended with that method. Again, this doesn't solve every problem, but it does allow interfaces to be somewhat more flexible.
There's a couple different ways you could do something like this. I personally haven't worked with EF so I can't speak in regards to how it will work.
Option One: Interfaces
public interface IAuditable
{
Guid RowGUID { get; }
Guid InsertUserGUID { get; }
Guid UpdateUserGUID { get; }
Guid DeleteUserGUID { get; }
DateTime UpdateDate { get; }
DateTime InsertDate { get; }
DateTime DeleteDate { get; }
}
Of course you can change it to get and set if your use cases need that.
Option Two: Super/base classes
public abstract class AuditableBase
{
// Feel free to modify the access modifiers of the get/set and even the properties themselves to fit your use case.
public Guid RowGUID { get; set;}
public Guid InsertUserGUID { get; set;}
public Guid UpdateUserGUID { get; set;}
public Guid DeleteUserGUID { get; set;}
public DateTime UpdateDate { get; set;}
public DateTime InsertDate { get; set;}
public DateTime DeleteDate { get; set;}
// Don't forget a protected constructor if you need it!
}
public class SomeModel : AuditableBase { } // This has all of the properties and methods of the AuditableBase class.
The problem with this is that if you cannot inherit multiple base classes, but you can implement multiple interfaces.
I just started using Entity Framework and it created a Context class which I can use to get all the data i need from it. But I am facing an issue on how I should organize my code, by watching the demos, the person just uses the framework and codes everything on a console application. What is the best way to use Entity Framework and that it looks clean?, what I mean by this is...right now using aspx pages, I could just use the aspx.cs to get the data or save the data. But I do not want this, I would like it to be more organized although the Entity Framework did almost everything by creating the objects etc.. but still, I need to use things like
using(var myobject = new MyContextData())
{
blah blah..
}
would you say that it would be nicer to write classes that would wrap these calls?. I would really appreciate any inputs as it would really make me a better programmer using the entity framework.
Regards
This question should everyone, who provides some tutorial about EF, ask. It is hard to say what is the best way, but put all code in the codebehind classes (aspx.cs) does not help extensibility and testability. Please, try to read this article:
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Not only it is official tutorial on asp.net, but it mostly shows, that Framework EF could be used correctly in currently fancy Repository pattern
Edit:
I think that Generic Repository is Anti Pattern. But I do not understand #TomTom comment.
Original Answer:
As Radim Köhler mentioned you need to implement Repository and Unit of Work patterns
But the article he provided in my opinion is not fully correct.
At my current job I use following implementation of these patterns.
For example, we have three types of entities: Person, Good and Order. I created repository for Persons. In common case Repository must not be generic. It must contain methods which represent specific queries for this entity. So by looking at the interface of repository you can tell what kinds of queries executed for entity (Person, e.g.). As you will see I created DTO for Person called PersonWrap. For creating PersonWrap from Person and updating Person from PersonWrap you can use AutoMapper instead of PersonWrap() constructor and Update() method. Because EntityFramework DbContext implements Unit of Work pattern, you just need to provide created DbContext to repository methods. If repository method is a separate action and you do not need DbContext outside of this method you can create and dispose it inside this method.
public class Person {
public int Id { get; set; }
public string FirstName { get; set; }
public string SecondName { get; set; }
public DateTime RegistrationDate { get; set; }
public List<Order> Orders { get; set; }
}
public class Good {
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
public class Order {
public int Id { get; set; }
public Person Person { get; set; }
public Good Good { get; set; }
public int Count { get; set; }
}
public class MyDbContext: DbContext
{
public IDbSet<Person> Persons { get { return Set<Person>(); }}
public IDbSet<Good> Goods { get { return Set<Good>(); }}
public IDbSet<Order> Orders { get { return Set<Order>(); }}
}
public class PersonRepository {
public IEnumerable<Person> GetAll() {
using (var context = new MyDbContext()) {
return context.Persons.ToList();
}
}
public IEnumerable<Person> GetLastWeekPersons() {
using (var context = new MyDbContext()) {
return context.Persons.Where(p => p.RegistrationDate > new DateTime().AddDays(-7)).ToList();
}
}
public Person GetById(int id, MyDbContext context) {
return context.Persons.Include(p => p.Orders).FirstOrDefault(p => p.Id == id);
}
public Person GetById(int id) {
using (var context = new MyDbContext()) {
return GetById(id, context);
}
}
}
public class PersonWrap {
public int Id { get; set; }
public string FirstName { get; set; }
public string SecondName { get; set; }
public int OrderCount { get; set; }
public PersonWrap(Person person) {
Id = person.Id;
FirstName = person.FirstName;
SecondName = person.SecondName;
OrderCount = person.Orders.Count;
}
public void Update(Person person) {
person.FirstName = FirstName;
person.SecondName = SecondName;
}
}
public class PersonDetailsViewController {
public PersonWrap Person { get; protected set; }
public PersonDetailsViewController(int personId) {
var person = new PersonRepository().GetById(personId);
if (person != null) {
Person = new PersonWrap(person);
}
}
public void Save() {
using (var context = new MyDbContext()) {
var person = new PersonRepository().GetById(Person.Id, context);
Person.Update(person);
context.SaveChanges();
}
}
}
You are on the right track for creating classes to handle your EF.
The biggest benefit for doing it this way is able to unit test easily.
Test early and test often is always a good idea.
I suggest putting your EF related classes in a separate project.
I have an entity class Person and its corresponding DTO class PersonDto.
public class Person: Entity
{
public virtual string Name { get; set; }
public virtual string Phone { get; set; }
public virtual string Email { get; set; }
public virtual Sex Sex { get; set; }
public virtual Position Position { get; set; }
public virtual Division Division { get; set; }
public virtual Organization Organization { get; set; }
}
public class PersonDto: Dto
{
public string Name { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public Guid SexId { get; set; }
public Guid PositionId { get; set; }
public Guid DivisionId { get; set; }
public Guid OrganizationId { get; set; }
}
After receiving a DTO object I have to convert it into a person entity. Now I do it completely manually. The code looks like this.
public class PersonEntityMapper: IEntityMapper<Person, PersonDto>
{
private IRepository<Person> _personRepository;
private IRepository<Sex> _sexRepository;
private IRepository<Position> _positionRepository;
private IRepository<Division> _divisionRepository;
private IRepository<Organization> _organizationRepository;
public PersonEntityMapper(IRepository<Person> personRepository,
IRepository<Sex> sexRepository,
IRepository<Position> positionRepository,
IRepository<Division> divisionRepository,
IRepository<Organization> organizationRepository)
{
... // Assigning repositories
}
Person Map(PersonDto dto)
{
Person person = CreateOrLoadPerson(dto);
person.Name = dto.Name;
person.Phone = dto.Phone;
person.Email = dto.Email;
person.Sex = _sexRepository.LoadById(dto.SexId);
person.Position = _positionRepository.LoadById(dto.PositionId);
person.Division = _divisionRepository.LoadById(dto.DivisionId);
person.Organization = _organizationRepository.LoadById(dto.OrganizationId);
return person;
}
}
The code is in fact trivial. But as the number of entities grows so does the number of mapper classes. The result is lots of similar code. Another issue is that when there are mode associations I have to add constructor parameteres for additional repositories. I tried to inject a some kind of a repository factory instead, but it smelled a bad-known Service Locator so I reverted to an original solution.
Unit testing of these mappers also results in a number of similar-looking test methods.
With all this been said I wonder if there exists a solution that can reduce the amount of manually written code and make the unit testing easier.
Thanks in advance.
UPDATE
I'd accomplished the task with Value Injecter but then I realized that I could safely remove it and the rest would still work. Here is the resulting solution.
public abstract class BaseEntityMapper<TEntity, TDto> : IEntityMapper<TEntity, TDto>
where TEntity : Entity, new()
where TDto : BaseDto
{
private readonly IRepositoryFactory _repositoryFactory;
protected BaseEntityMapper(IRepositoryFactory repositoryFactory)
{
_repositoryFactory = repositoryFactory;
}
public TEntity Map(TDto dto)
{
TEntity entity = CreateOrLoadEntity(dto.State, dto.Id);
MapPrimitiveProperties(entity, dto);
MapNonPrimitiveProperties(entity, dto);
return entity;
}
protected abstract void MapNonPrimitiveProperties(TEntity entity, TDto dto);
protected void MapPrimitiveProperties<TTarget, TSource>(TTarget target, TSource source, string prefix = "")
{
var targetProperties = target.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).OrderBy(p => p.Name);
var sourceProperties = source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).OrderBy(p => p.Name);
foreach (var targetProperty in targetProperties) {
foreach (var sourceProperty in sourceProperties) {
if (sourceProperty.Name != string.Format("{0}{1}", prefix, targetProperty.Name)) continue;
targetProperty.SetValue(target, sourceProperty.GetValue(source, null), null);
break;
}
}
}
protected void MapAssociation<TTarget, T>(TTarget target, Expression<Func<T>> expression, Guid id) where T : Entity
{
var repository = _repositoryFactory.Create<T>();
var propertyInfo = (PropertyInfo)((MemberExpression)expression.Body).Member;
propertyInfo.SetValue(target, repository.LoadById(id), null);
}
private TEntity CreateOrLoadEntity(DtoState dtoState, Guid entityId)
{
if (dtoState == DtoState.Created) return new TEntity();
if (dtoState == DtoState.Updated) {
return _repositoryFactory.Create<TEntity>().LoadById(entityId);
}
throw new BusinessException("Unknown DTO state");
}
}
Mapping of each entity is performed with a concrete class derived from BaseEntityMapper. The one for Person entities looks like this.
public class PersonEntityMapper: BaseEntityMapper<Person, PersonDto>
{
public PersonEntityMapper(IRepositoryFactory repositoryFactory) : base(repositoryFactory) {}
protected override void MapNonPrimitiveProperties(Person entity, PersonDto dto)
{
MapAssociation(entity, () => entity.Sex, dto.SexId);
MapAssociation(entity, () => entity.Position, dto.PositionId);
MapAssociation(entity, () => entity.Organization, dto.OrganizationId);
MapAssociation(entity, () => entity.Division, dto.DivisionId);
}
}
Explicitly calling MapAssociation protects against future properties renamings.
You can have a look on the two most used Object-Object mapper:
AutoMapper
AutoMapper is a simple little library built to solve a deceptively
complex problem - getting rid of code that mapped one object to
another. This type of code is rather dreary and boring to write, so
why not invent a tool to do it for us?
Value Injecter
ValueInjecter lets you define your own convention-based matching
algorithms (ValueInjections) in order to match up (inject) source
values to destination values.
There is a comparison article on SO: AutoMapper vs ValueInjecter
You can use GeDA for mapping any entity to a DTO object, it comes with either annotations or DSL support.
http://inspire-software.com/confluence/display/GeDA/FAQ
There are only basic examples on the wiki but jUnits of source code are full of useful examples
You can get it from sourceforge or google code manually or via maven dependency
Details are here: http://inspire-software.com/confluence/display/GeDA/GeDA+-+Generic+DTO+Assembler
I want to implement default object pattern for my all classes in the inheritance tree. I am doing as shown below.
namespace test
{
public class Record
{
public int ID { get; set; }
}
public class StudentRecord : Record
{
public string StudentID { get; set; }
}
public class DriverRecord : Record
{
public string DLNumber { get; set; }
}
public class client
{
public static void Main()
{
StudentRecord st = StudentRecord.Default;
DriverRecord dr = DriverRecord.Default;
}
}
}
I want the default property or method to initialize all the class level properties to their defaults and I don’t want to repeat the implementation for each class. I just want to write on Record (base ) class . Can you provide some suggestions on this?
What you’re looking for is exactly what constructors are for. A constructor can call an inherited base constructor, so you need to do the base initialisation in only one place. Sometimes the basic functionality really does what you need :)
public class Record
{
public int ID { get; set; }
public Record()
{
// ... do general initialisation here ...
}
}
public class StudentRecord : Record
{
public string StudentID { get; set; }
public StudentRecord()
: base() // This calls the inherited Record constructor,
// so it does all the general initialisation
{
// ... do initialisations specific to StudentRecord here ...
}
}
public class client
{
public static void Main()
{
// This calls the constructor for StudentRecord, which
// in turn calls the constructor for Record.
StudentRecord st = new StudentRecord();
}
}
The Record class can only set the properties which are inherited by StudentRecord and DriverRecord. If you want to set class-specific properties to their default values you have to override the method (I would make a method) and do something like this (for StudentRecord ):
public void override Initialize()
{
base.Reset();
this.StudentId = 0;
}
HTH
You don't have any "class level properties", i.e. static properties, in your code sample. The properties you do have (the instance properties) are already initialized to their defaults -- 0 for integers, null for references, etc.
If you want to define your own defaults -- perhaps ID should default to -1 until you save, and the strings should default to "" -- then that's exactly what constructors are for:
public class Record
{
public Record() { ID = -1; }
public int ID { get; set; }
}
public class StudentRecord : Record
{
public StudentRecord() { StudentID = ""; }
public string StudentID { get; set; }
}
// etc.
If you want something different from either of those, you'll have to explain what you're looking for.
I think Null Object Pattern is what you need.