When creating a new ASP.NET MVC3 application, in the default project there is a Models
folder. This Models
folder includes the AccountModels
- RegisterModel
, LoginModel
, etc.
I have a separate project for the DAL - it includes a repository
and a service
.
Now, I have a method in my service
:
TblUser Register(RegisterModel model);
For this to work, I must reference the web project in my data project.
Is this appropriate, or should I include my Models
folder in my data project instead?
Your first option is not appropriate. That's what's referred to as a circular dependency and it is bad.
Your second option is better, but still not great. Your model classes will undoubtedly have fields and methods which are applicable to your ui only. Those don't belong in your data layer any more than your data objects belong in your web tier. That's an example of coupling - also known as a poor separation of concerns - and it is also bad.
The best option is to separate out data which is needed by both tiers out into a distinct set of classes (sometimes referred to as dto's - data transfer objects - or poco's - plain old class objects). Those classes can reside in your data project or in a project entirely to themselves depending on your needs. If your service resides in a WCF service, these classes will typically be DataContracts. Then, within your MVC project you should have your models, as they are now, but they should contain references to your POCO's instead of holding any data of their own. So in your specific case you would create a RegistrationInfo class (or whatever you want to call it) in your data project, then add a field of type RegistrationInfo to your model and pass it to your service instead of the entire RegistrationModel.
EDIT: added an example
namespace MyProject.Data.Objects {
public class RegistrationInfo {
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
[Required]
public string Email { get; set; }
}
}
namespace MyProject.Data {
public class MyService {
public TblUser Register(RegistrationInfo info) {
// .. save to the database ..
}
}
}
namespace MyProject.UI.Models {
class RegistrationModel {
public RegistrationInfo Info { get; set; }
/* Fields which the ui needs but the database does not */
public bool ConfirmPassword { get; set; }
public bool AllowFreeEmailAddresses { get; set; }
public void Save() {
new MyProject.Data.MyService().Register(this.Info);
}
public RegistrationModel() {
this.Info = new RegistrationInfo();
}
}
}