Mapster.Tool use codegen to generate mappers but not DTOs - c#

Can I use Mapster.Tool to generate Mappers without also generating the class that I'm mapping to? I have a typical Domain objects to and from DTOs scenario but the sample code here
https://github.com/MapsterMapper/Mapster/tree/master/src/Sample.CodeGen
and the documentation here
https://github.com/MapsterMapper/Mapster/wiki/Mapster.Tool
both focus on generating the DTOs from the Domain objects, either by annotating them with attributes or using configuration. There is configuration to create DTOs that are CRU specific but I'd still rather create my own DTOs but not have to create my own mappings.

Yes you can - take a look at the interface based code gen documented here.
This allows you to define an interface that will generate a mapper based on existing classes.
From there you can choose how to consume the mapper that's generated. Register in services and then use DI being one way.
Here is a quick example:
[Mapper]
public interface IContactMapper
{
ContactDetailVm MapTo(Contact contact);
}
Would result in
public partial class ContactMapper : IContactMapper
{
public ContactDetailVm MapTo(Contact p2)
{
return p2 == null ? null : new ContactDetailVm()
{
Id = p2.Id,
Created = p2.Created,
LastUpdate = p2.LastUpdate,
Title = p2.Title,
FirstName = p2.FirstName,
LastName = p2.LastName,
PreferredName = p2.PreferredName,
BirthYear = p2.BirthYear
};
}
}
I don't believe you can use the tool to generate the mapping extension methods for existing entities however. At least im not aware it can be done in v6.

Related

C# On property change, run logic

I have a C# Entity which is auto generated via database first:
public partial class Zone
{
public Guid LocationId {get; set;}
...
}
What I need to do is run a function, Process() whenever LocationId is changed. Now normally I would alter the setter and job done, however because this is auto generated via database first, any "manual changes to the file will be overwritten if the code is regenerated."
What would be the best approach here?
The current thinking is to create a new partial class to do something like this:
public partial class Zone
{
private Guid _pendingLocationId
public Guid PendingLocationId {
get { return _pendingLocationId }
set {
Guid updatedLocation = Process(value) ?? value;
_pendingLocationId = updatedLocation;
locationId = updatedLocation;
}
}
}
Just a note; the unfortunate reality is that there is probably zero chance of us integrating a new framework or library into the application at this stage.
In response to the possible duplicate flag; Unless I have misread, this would require us re-mapping /encapsulating all of our Zone references into a new class, not only pushing this out to all the views, but also editing many linq queries etc. If someone can identify why this would be the preferred solution over my own suggested solve, then please let me know.
The least intrusive way to do this might be using AOP patterns, for instance, using PostSharp framework: less than 2 lines of code!
[NotifyPropertyChanged] //<---Add this attributes to the class
public class Zone
{
public Guid LocationId {get; set;}
...
}
To hook the changed event and add your own handler
//Zone instance;
((INotifyPropertyChanged) instance).PropertyChanged += ZoneOnPropertyChanged;
More details can be found here.
Update: the OP mentioned zero chance of integrating other library into the app, I am just curious, don't you use nuget? and what is the reason of this zero chance? In my personal view, you should, rather than NOT, to reinvent the wheels, if there is already a library which does the required features.
If licensing cost is the issue or it is overkill or to heavy to introduce this bulky library just for the sake of the problem, I think Fody, a free open source alternative to PostSharp can be considered. More specifically PropertyChanged.Fody package, which is very standalone, compact and light weight.
I would suggest using AutoMapper.
You can write another class with the same name and properties (with INPC), but in different namespace. Then, everytime you fetch database, you use Automapper to map the data into your notifiying class and everytime you save data to database you map it back.
That way you only need to change namespaces in code using your class and add code like this into your repository:
var dtos = args.Select(x => Mapper.Map<Zone>(x)).ToList();
Have a business entity mapped to yr database entity (via AutoMapper) and then in your business entity, incorporate the INotifyPropertyChanged interface.
Pseudo code below. This will de-couple your database from business entity and allow independent changes.
namespace DBEntity {
public class Customer {
public int Id { get; set; } ...
}
}
namespace BizEntity {
public class Customer : INotifyPropertyChanged {
private int id;
public int Id {
get { return this.id } ;
set {
this.id = value;
PropertyChanged(Id...);
}
}
NotifyPropertyChanged() {
....
}
var dbCustomer = GetCustomerFromDB()
var cust = AutoMapper.Mapper.Map<DBEntity.Customer, BizEntity.Customer>(dbCustomer);
// Update the property as per biz requirement
cust.Id = 53656; // Fires the Notification
Let me know if this helps.
Regarding AutoMapper as a new library, this will be a minimum change and there's no licensing or learning curve required here to allow fast integration.

Whats the best practice of linq ASP.NET MVC respository pattern

I'm a junior web developer trying to learn more every day.
What it the best practice for you guys to performe MVC repository pattern with Linq?
The one I use:
Create extra clases with the exact name of my .tt files with CRUD method like getAll(), getOne(), Update(), Delete() filling my own class with the entity framework and returning this, or using the entity framework crude
this is an example of what I'm actually doing.
this is my getAll method of my class for example User
public class CEmployee : CResult
{
public string name{get;set;}
public string lastname{get;set;}
public string address{get;set;}
//Extracode
public string Fullname // this code is not in the .tt or database
{
get
{
return name + lastname;
}
}
public <List>CEmployee getAll()
{
try
{
var result = (from n in db.Employee
select new CEmployee // this is my own class I fill it using the entity
{
name = n.name,
lastname = n.lastname,
address = n.address
}).ToList();
if (result.Count > 0)
{
return result;
}
else
{
return new List<CResult>
{
new CResult
{
has_Error = true,
msg_Error = "Element not found!!!!"
}
}
}
}
catch
{
return Exception();
}
}
}
that the way I do all thing I return a filled of my type, but on the web I see that people return the entity type normaly, But I do this to manipulate my response, And if I want to return extra information I just have to neste a list for example, whats the best way guys, return mytype or return the entity type ?
PD, I also use this class like my ViewModel.And I do this for all my classes.
One of the projects I am currently one uses Dependency Injection to setup the DAL (Data Access Layer.) We also are using an n-Tier approach; this separates the concern of the repository from the Business Logic and Front End.
So we would start with 4 or so base projects in the application that link to each other. One of that handles the Data Access, this would be your repository; read up on Ninject for more info on this. Our next tier is our Domain which houses the Entities built by the t4 template(.tt files) and also our DTO's (data transfer objects which are flat objects for moving data between layers.) Then we have a service layer, the service layer or business logic layer holds service objects that handle CRUD operations and any data manipulation needed. Lastly we have our front end which is the Model-View-ViewModel layer and handles the controllers and page building.
The MVVM calls the services, the service objects call the data access layer and Entity Framework works with Ninject to access the data and its stored in the DTO's as it is moved across layers.
Now this may seem overly complex depending on the application you are writing, this is built for a highly scalable and expandable web application.
I would highly recommend going with a generic repository implementation. The layers between your repository and the controller vary depending on a number of factors (which is kind of a broader/bigger topic) but the generic repository gets you going on a good implementation that is lightweight. Check out this article for a good description of the approach:
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Ideally in a MVC application, you will want to repositories in a different layer like in a separate project, let's call it Data layer.
You will have an IRepository interface that contain generic method signatures like GetAll, GetById, Create or UpdateById. You will also have abstract RepositoryBase class that contain shared implementation such as Add, Update, Delete, GetById, etc.
The reason that you use an IRepository Interface is, there are contracts for which your inherited repository class, such as EmployeeRepository in your case, need to provide concrete implementations. The abstract class serves as a common place for your shared implementation (and override them as you need to).
So in your case, what you are doing using LINQ with your DbContext is basically correct, but implementation like your GetAll method should be part of the generic/shared implementation in your abstract class RepositoryBase:
public abstract class RepositoryBase<T> where T : class
{
private YourEntities dataContext;
private readonly IDbSet<T> dbset;
protected RepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
dbset = DataContext.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
protected YourEntities DataContext
{
get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
}
public virtual T GetById(long id)
{
return dbset.Find(id);
}
public virtual T GetById(string id)
{
return dbset.Find(id);
}
public virtual IEnumerable<T> GetAll()
{
return dbset.ToList();
}
}
I would suggest you need to think about whether or not to return an error result object like CResult, and think about if your CEmployee and CResult should exist in this parent-child relationship. Also think about what you want to do with your CResult Class. It seems to me your CEmployee handles too many tasks in this case.

Map domain model to different persistence stores with different primary key datatypes

I need to develop an application that, for different customers, needs to target different existing legacy databases as persistence store, or that could also be able to run completely stand-alone with its own independent database.
So my approach is:
Develop the domain model independently from the final persistence store
Use an EF Code-First repository implementation to map it to its own standalone database if needed
Use other repository implementations to map it to the legacy databases systems if needed
I know for a fact that one of the targetted existing systems is a CRM 2011 system. The "CRMRepository" implementation would best use the Microsoft CRM SDK I guess, instead of directly targetting the underlying SQL database.
But, CRM uses GUIDs as its primary keys for all its entities, while the other database systems will mostly use integers.
So I'm kinda confused on what the best approach is to design my domain entities to later not run into problems when mapping it to the persistence stores in the repository implementation.
A typical domain entity would be
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
For the standalone solution: use a code-first based EF repository, no problem
For targeting an existing database with ints as Primary Keys: map it to the correct primary key property, no problem
However, how to target a CRM backend ? A "Person" entity would typically map to the "Account" entity in CRM, however there the PK is accountid, which is a GUID, as with all other CRM entities.
Should I change my domain entities to use strings as primary key properties, so it can accomodate all kinds of datatypes, and then perform the conversion to and from the correct datatype inside each repository implementation ? Or are there other and better ways to tackle this ?
One of the things I thought of would be to declare all my 'Id' properties as type object, and then use the repository pattern along with Automapper to implement specific implementations and map my domain objects to for instance EF Entities (which would then have PKs of type int) in a EFRepository implementation.
For the CRM implementation of the repository, the repo would use the CRM SDK and map the 'object Id' on the GUIDs internally used by CRM.
Could that be a viable solution, or is it too far fetched ?
Thanks
EDIT 1: I'm open for commercial solutions. Could the use of LLBLGen be an option here ? Have zero experience with it but it looks like it does not allow you to reuse the same domain definition into separate "repository" implementations, or am I wrong ?
EDIT 2: Current solution structure overview, trying to follow onion architecture. Different repository implementations would go into "Infrastructure". Repository implementation would then be "pluggable" by customer by means of DI.
Looks like you have two options.
Define Id as an Object, then it doesn't matter what the repository uses, it'll just expect it to be the same time that it saves. This comes at the small cost of requiring explicit casts and handling failures.
Create an int Id and a Guid GuidId. This removes the cost of the explicit casts and may help in type safety. Also means you'll have issues if some other system uses a long or a string as the id.
I had a similar situation. Different types of companies had different information, were handled differently, and mapped to older legacy tables with ints and guids as primary keys etc.
What I ended up going with was a base (set to abstract in EF) table with a GUID primary key and all shared common data), I then had an inheriting table for each type (primary key of these tables is foreign key on base). In these I am able to declare any specific information about that specific type and link them to other older or new tables.
In your case, you could have a base Customer Type, but then declare as many different types of customers as you like and extend and link them as and when you need. You can then target them as such:
var baseCust = db.Customers.FirstOrDefault(x => x.Id == someId);
if(baseCust is CustTypeA)
{
// Access extended properties and Legacy tables (via lazy loading)
var custA = (CustTypeA)baseCust;
custA.SomeExtendedProperty = blah;
var oldCompletedOrders = custA.Orders.Where(x => x.Completed).ToList();
//etc
This gave us the flexibility to move forward and access all the old rubbish that they wanted to see.
How about having all my domain objects inherit from an abstract base class Entity and then use a property "public TKey Id {get; set;}". Or even on a per class basis if I am to allow different types of keys on different domain objects. Would that be a viable solution, keep in mind that the repository implementation could be anything ranging from EF to NHibernate to a custom repo like CRM?
You could implement a few interfaces and a base repository (I've read about something like this else where.) Please consider the following linqpad script (I only used dump for verification purposes):
void Main()
{
var personList = new List<PersonSql>
{
new PersonSql
{
Id = 1,
FirstName = "Some",
LastName = "Person"
}
}.AsQueryable();
var repo = new PersonRepo();
repo.Query = personList;
repo.GetById(1).Dump();
}
// Define other methods and classes here
//entity base
class BaseEntity<TKey>
{
public TKey Id { get; set; }
}
//common constructs
class PersonBase<Tkey> : BaseEntity<Tkey>
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
//actual entity with type of int as the id
class PersonSql : PersonBase<int>
{
}
//and so on
class PersonNoSql : PersonBase<string>
{
}
//likley you would generate these or code them based on your data source when creating your mapping classes.
//repositories
interface IRepository<TEntity, TKeyI>
where TEntity : BaseEntity<TKeyI>
{
IQueryable<TEntity> Query {get; set;}
TEntity GetById(TKeyI key);
//Other Repository Methods here
}
abstract class RepoBase<TBaseEntity, TKeyB> : IRepository<TBaseEntity, TKeyB>
where TBaseEntity : BaseEntity<TKeyB>
{
//Base Implementations Here
public IQueryable<TBaseEntity> Query { get; set; }
public virtual TBaseEntity GetById(TKeyB key)
{
throw new NotImplementedException();
}
}
abstract class PersonRepoBase<TkeyType> : RepoBase<PersonBase<TkeyType>, TkeyType>
{
public override PersonBase<TkeyType> GetById(TkeyType key)
{
//Get a person.
throw new NotImplementedException();
}
}
//class PersonRepo : RepoBase<PersonNoSql, string>
//{
// public override PersonNoSql GetById(string id)
// {
// throw new NotImplementedException();
// }
//}
class PersonRepo : RepoBase<PersonSql, int>
{
public override PersonSql GetById(int id)
{
return Query.First(x => x.Id == id);
throw new NotImplementedException();
}
}
What do you gain doing it this way? Well, its a repository. Its strongly typed with Generic Constraints. My initial thought for doing it this way was to have a base implementation of GetById, but my compiler was not intelligent enough to determine they TKeyB between the BaseRepo and BaseEntity as Constrained on BaseRepo were the same type. So it didn't give me the benefit of a base implementation. All the same, maybe you could give it a try and refine to suit your needs.
However, it may just be better to do as other have suggested and deal with having the Id as an object on your home domain for a given model.

DTO naming conventions , modeling and inheritance

We are building a web app using AngularJS , C# , ASP.Net Web API and Fluent NHibernate.
We have decided to use DTOs to transfer data to the presentation layer ( angular views).
I had a few doubts regarding the general structuring and naming of DTOs.
Here's an example to illustrate my scenario.
Lets say I have a domain entity called Customer which looks like:
public class Customer
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Address Address { get; set; }
public virtual ICollection<Account> Accounts { get; set; }
}
Now, in my views/presentation layer I need to retrieve different flavors of Customer like :
1) Just Id and Name
2) Id , Name and Address
3) Id , Name , Address and Accounts
I have created a set of DTOs to accomplish this :
public class CustomerEntry
{
public int Id { get; set; }
public string Name { get; set; }
}
public class CustomerWithAddress : CustomerEntry
{
public AddressDetails Address { get; set; }
}
public class CustomerWithAddressAndAccounts : CustomerWithAddress
{
public ICollection<AccountDetails> Accounts { get; set; }
}
AddressDetails and AccountDetails are DTOs which have all the properties of their corresponding Domain entities.
This works fine for querying and data retrievals ; the question is what do I use for inserts and updates. During creation of a new customer record , name and address are mandatory and accounts are optional ..so in other words I need an object with all the customer properties. Hence the confusion :
1) What do I use for insert and updates?
The CustomerWithAddressAndAccounts DTO has everything in it but its name seems a bit awkward to be used for insert/updates.
2) Do I create another DTO .. if I do , wouldn't that be duplication as the new DTO will exactly be like CustomerWithAddressAndAccounts ?
3) Last but not least , does the DTO inheritance strcuture described above seem like a good fit for the requirement ? Are there any other ways to model this ?
I have gone through other posts on this topic but couldn't make much headway.
One thing that I did pickup was to avoid using the suffix "DTO" in the class names.
I think it feels a bit superfluous.
Would love to hear your thoughts
Thanks
Recommendation is that you should just have one DTO class for each entity suffixed with DTO e.g. CustomerEntryDTO for the Customer entity (but you can certainly use inheritance hierarchies as per choice and requirements).
Moreover, Add a abstract DTOBase kind of base class or an interface; and do not use such deep inheritance heirarchies for each Address, Account and other properties to be included in child DTOs. Rather, include these properties in the same CustomerEntryDTO class (if possible) as below:
[Serializable]
public class CustomerEntryDTO : DTOBase, IAddressDetails, IAccountDetails
{
public int Id { get; set; }
public string Name { get; set; }
public AddressDetails Address { get; set; } //Can remain null for some Customers
public ICollection<AccountDetails> Accounts { get; set; } //Can remain null for some Customemer
}
Moreover, your DTOs should be serializable to be passed across process boundaries.
For more on the DTO pattern, refer below articles:
Data Transfer Object
MSDN
Edit:
In case you don't want to send certain properties over the wire (I know you would need to that conditionally so would need to explore more on this), you can exclude them from the Serialization mechanism by using attributes such as NonSerialized (but it works only on fields and not properties, see workaround article for using with properties: NonSerialized on property).
You can also create your own custom attribute such as ExcludeFromSerializationAttribute and apply it to properties you don't want to send every time over wire based on certain rules/conditions. Also see: Conditional xml serialization
Edit 2:
Use interfaces for separating the different properties in the one CustomerEntryDTO class. See the Interface Segregation Principle on Google or MSDN. I will try to put a sample explanation later.
What do I use for insert and updates?
Service operations are usually defined in very close relation to business operations. Business language doesn't speak in terms of "inserts" and "updates", neither do services.
Customer management service is likely to have some Register operation that takes customer name and maybe some other optional parameters.
Do I create another DTO?
Yes, you should create another DTO.
Sometimes service operation contract may be enough and there is no need to define a separate DTO for a particular operation:
function Register(UserName as String, Address as Maybe(of String)) as Response
But most of the time it is better to define a separate DTO class even for only a single service operation:
class RegisterCommand
public UserName as String
public Address as Maybe(of String)
end class
function Register(Command as RegisterCommand) as Response
RegisterCommand DTO may look very similar to CustomerWithAddress DTO because it has the same fields but in fact these 2 DTOs have very different meanings and do not substitute each other.
For example, CustomerWithAddress contains AddressDetails, while a simple String address representation may be enough to register a customer.
Using a separate DTO for each service operation takes more time to write but easier to maintain.
As of your item 1, for inserts and updates it's better to use Command pattern. According to CQRS, you don't need DTOs. Consider this schema:
via blogs.msdn.com

Circular Dependancy on Interface

I'm in the process of re-factoring and structuring a Win8 App Solution. I've been separating out my key components into their own projects. I have:
The main Win8 project which uses MVVMLight (and therefore SimpleIOC)
A Model project containing all my serialisable model classes
A Services project with various classes for navigation and serialisation
A Contracts project for all of my Interfaces
A View Models project containing the view models used by the main app.
So far I've got things working but have one case where I can't work out the best structure. Within my ViewModels project I have a data mapper class. Basically it takes in a model and spits out a view model. I've been trying to move this to the service layer and created an Interface for it but ran into a dependency within the Interface for knowledge of the ViewModel classes, so have essentially a circular dependency at the moment.
EDIT: I should explain that the ViewModels themselves need to utilise this mapper. For example I have an overall PageViewModel which holds everything the XAML page requires. One of these things is a list of VehicleViewModels which is a list of vehicles that contains some view specific properties. So the PageViewModel will call into the data service, get a Vehicle model and then use the mapper to turn this into the VehicleViewModel.
Here is the interface.
namespace MyApp.Contracts
{
public interface IDataMapperService
{
VehicleViewModel VehicleToVehicleViewModel(Vehicle v);
TripViewModel TripToTripViewModel(Trip t);
}
}
As you can see, I want to return a ViewModel object from the two methods. However the ViewModel project already has a reference to this Contracts project, so I this currently won't build.
I toyed with the idea of creating and Interface for the viewmodels but then I'd have lots of work to create the interfaces and I'm not sure that's the best way. Have I overlooked something obvious here?
EDIT: Here's an actual implementation of the current Interface:
public VehicleViewModel VehicleToVehicleViewModel(Vehicle v)
{
var newVehicle = new VehicleViewModel(v.VehicleID, v.Make, v.Model, v.Petrol, v.Registration);
foreach (Trip t in v.Trips)
{
newVehicle.Trips.Add(TripToTripViewModel(t));
}
IQueryable<Trip> trips = v.Trips.AsQueryable();
var now = DateTime.Now.Date;
var firstofmonth = new DateTime(now.Year, now.Month, 1);
while (now.DayOfWeek != DayOfWeek.Monday) now = now.AddDays(-1);
var weektrips = from t in trips
where t.Date >= now
select t;
var monthtrips = from t in trips
where t.Date >= firstofmonth
select t;
newVehicle.TripsThisWeek = weektrips.Count();
newVehicle.MilesThisWeek = (int)Math.Round(weektrips.Sum(t => t.Mileage), 0);
newVehicle.TripsThisMonth = monthtrips.Count();
newVehicle.MilesThisMonth = (int)Math.Round(monthtrips.Sum(t => t.Mileage), 0);
return newVehicle;
}
public TripViewModel TripToTripViewModel(Trip t)
{
var newTrip = new TripViewModel(t.TripID, t.Date, t.Mileage);
return newTrip;
}
You could use generics to create your mapper interface.
namespace MyApp.Contracts
{
public interface IDataMapperService<ViewModelT, ModelT>
{
ViewModelT ModelToViewModel(ModelT v);
}
}
Your service could then return an IDataMapperService<VehicleViewModel, Vehicle> and an IDataMapperService<TripViewModel, Trip>. You could create lightweight interfaces for view models and models to use with generic constraints.
namespace MyApp.Contracts
{
public interface IModel {}
public interface IViewModel {}
public interface IDataMapperService<ViewModelT, ModelT>
where ViewModelT : IViewModel
where ModelT : IModel
{
ViewModelT ModelToViewModel(ModelT v);
}
}
Then, to implement your new interface, you'd create a mapper class.
public class DataMapperService : IDataMapperService<VehicleViewModel, Vehicle>
{
public VehicleViewModel ModelToViewModel(Vehicle v)
{
//implementation goes here
}
}
Obviously, you will need to implement this class in a project that references your contracts, models, and viewmodels projects.
If I am understanding the question correctly you are trying to map from one object to a view model. If this is the case writing your own mapper tool may not be super efficiant for your usage. Check out Automapper It will allow you to map one object to another type by calling the Mapper.Map() method.
It looks to me like you are over thinking what you actually want to accomplish. If you need a VehicleViewModel then map the vehicle to the VehicleViewModel and call your mapping method. Automapper makes doing this super easy. But in general you just need a go-between mapper that lives on whatever layer can access your view models and it does the mapping for the different types.

Categories