May be this is a stupid question.
I have some model class in a Asp.Net web api 2.2 application, which implements an interface ICountryOfOrigin.
I need to filter records by applying where clause as shown below. I have to repeat this logic in many controllers with different models which implement ICountryOfOrigin.
Is it possible to move the filtering logic into a separate method and apply it to the controller action through data annotation?
My intention is to eliminate the repeating code.
Is it possible?
//Interface
public Interface ICountryOfOrigin
{
string Country {get;set;}
}
//Model
public class Product : ICountryOfOrigin
{
..
string Country {get;set;}
}
//Action
public IHttpActionResult Get()
{
List<string> euCountries = GetEuCountries();
Product product = _repository.Products.GetAll().Where(p=> euCountries.Contains(p.countries); // The filter is applied here
return Ok(products);
}
//Need to achieve something like this
[EuCountriesOnly]
public IHttpActionResult Get()
{
List<string> euCountries = GetEuCountries();
Product product = _repository.Products.GetAll();
return Ok(products);
}
Any experts help me on this?
I guess I would shoot anybody who would implemented it the way you want. Believe me, it's not cool at all to alter behavior of some method you're calling with an attribute you put on a calling method.
Just put the logic into an extension method on your repository type and call it a day:
public static class RepoExtensions
{
private static readonly euCountries = new Country[]{};
public static IEnumerable<ICountryOfOrigin> GetEU(this Repository repo)
{
return repo.Products.GetAll().Where(p=> euCountries.Contains(p.countries);
}
}
I'm assuming that your repository is of type Repository, you'll need to put the real type instead of it.
I have a database setup using 'master/slave replication'. I have one master and (at least) one slave, possibly ā slaves. For simplicity from here on I'll talk about one master, one slave because determining which slave to use includes some business-logic not relevant to the actual problem at hand.
Here's a schematic of the setup (with ā slaves):
In the application (currently using Dapper) I have the following, simplified, code:
abstract class BaseRepo
{
private readonly string _readconn;
private readonly string _writeconn;
public BaseRepo(string readConnection, string writeConnection)
{
_readconn = readConnection; //Actually IEnumerable<string> for ā slaves
_writeconn = writeConnection;
}
private SqlConnection GetOpenConnection(string cnstring)
{
var c = new SqlConnection(cnstring);
c.Open();
return c;
}
public SqlConnection GetOpenReadConnection()
{
return this.GetOpenConnection(_readconn);
// Actually we use some business-logic to determine *which* of the slaves to use
}
public SqlConnection GetOpenWriteConnection()
{
return this.GetOpenConnection(_writeconn);
}
}
class CustomerRepo : BaseRepo
{
// ...ctor left out for brevity...
// "Read" functions use the "read" connection
public IEnumerable<Customer> ListCustomers()
{
using (var c = this.GetOpenReadConnection())
{
return c.Query<Customer>("select * from customers order by name");
}
}
// "Write" functions use the "write" connection
public void UpdateCustomer(Customer cust)
{
using (var c = this.GetOpenWriteConnection())
{
c.Execute("update customers set name = #name where id = #id", cust);
}
}
}
My question is; suppose I want to use Entity Framework ("code first", should that be relevant) instead of Dapper; how would I best go about achieving the same concept; inserts/updates/deletes are executed against the "master" database and selects are executed against a slave (or any of the slaves). Does EF support this scenario at all? What would I need to do to make this work?
Additional info: I already use 'read-only' and 'write-only' users at the SQL Server level as a 'last line of defence' to prevent any mistakes in the DAL. What I'm looking for is a method of limiting my DAL to avoid having to catch SQL Server exceptions because of 'not allowed' actions and having to go to the (incorrect) SQL server in the first place before finding out the desired action is not allowed. I could use the same approach as I do now; instantiate/use the correct DbContext in the method itself (listcustomers/updatecustomer in the above example). I get that. But that would mean I'd have to create a 'wrapper' function for each "CRUD" action on each "entity" which was kind of why I was moving from dapper to EF in the first place; simply expose a DBSet and have EF take care of the changetracking/SQL queries etc. and now, hopefully, also figure out which connectionstring to use for each action.
As proposed by others, create a read/write context by default and then create a readonly one inheriting from it.
Also be sure to implement in a partial class a constructor accepting another configuration if you wish too.
public partial class CustomerEntities : DbContext
{
protected CustomerEntities(string nameOrConnectionString):base(nameOrConnectionString)
{
}
}
public class ReadonlyCustomerEntities : CustomerEntities
{
public ReadonlyCustomerEntities ()
: base("name=ReadonlyCustomerEntities")
{
}
public override int SaveChanges()
{
// Throw if they try to call this
throw new InvalidOperationException("This context is read-only.");
}
}
In a module of a win forms application I have a hierarchy of classes like BaseRecovery, LoanRecovery and FineRecovery. Both LoanRecovery and FineRecovery inherits from BaseRecovery. All these models have one view called RecoveryForm where you can enter/view loans and fines of employees. and I'm planing to use single Presenter class called RecoveryPresenter which inherits from BasePresenter. We have a DataService Class for db transactions
LoanRecovery class looks like this...
Class LoanRecovery : BaseRecovery
{
public string LoanID {get;set;}
public DateTime IssueDate {get;set;}
public Decimal Amount {get;set;}
.
.
.
}
So I'd do the following in Programe.cs.
IBaseRcovery recovery=null;
IRecoveryForm recoveryForm = new RecoveryForm();
IDataService dataService = new DataService();
BasePresenter presenter = new RecoveryPresenter( recovery, recoveryForm, dataService );
presenter.Show(); // This will display the form recoveryForm
In the presenter I would say
public RecoveryPresenter( IBaseRecover model, IRecoveryForm view, IDataService dataService )
{
this._Model = model;
this._View = view;
this._DataService = dataService;
WireUpViewEvents();
}
Now lets say if I need to give a loan, I would run SetModelPropertisFromView() mehtod in the BasePresenter class which use reflection. But before that I should pass an instance of LoanRecovery class (i.e. _Model) to that method together with _View. Like wise we can do same thing for all children classes as follows...
public void Issue()
{
if (_View.Type == "Loan")
{
_Model = new LoanRecovery();
SetModelPropertiesFromView(_Model, _View, _DataService);
_dataService.InsertLoan(_Model); //Error
}
if (_View.Type == "Fine")
{
_Model = new FineRecovery();
SetModelPropertiesFromView(_Model, _View, _DataService);
_DataService.InsertFine(_Model); //Error
}
if (_View.Type == "Insurance")
{
_Model = new InsuranceRecovery();
SetModelPropertiesFromView(_Model, _View, _DataService);
_DataService.InsertFine(_Model); //Error
}
}
Everything fine until the last line of the above if blocks. The issue is data access method in the DataService class required a child instance not a base class instance.
public void InsertLoan( LoanRecovery loan)
{
using (SqlConnection sqlConnection = new SqlConnection(db.GetConnectionString))
{
SqlCommand sqlCommand = new SqlCommand("BEGIN INSERT INTO recovery ;
sqlCommand.Parameters.Add("#empID", SqlDbType.Char).Value = loan.EmployeeID;
sqlCommand.Parameters.Add("#loanType", SqlDbType.VarChar).Value = loan.Type;
sqlCommand.Parameters.Add("#loanAmount", SqlDbType.Decimal).Value = loan.FullAmount;
sqlCommand.Parameters.Add("#loanDuration", SqlDbType.Int).Value = loan.Duration;
sqlConnection.Open();
sqlCommand.ExecuteNonQuery();
}
}
So I solved the problem as follows...
public void Issue()
{
if (_View.Type == "Loan")
{
LoanRecovery loanModel = new LoanRecovery(); //Creates a child instance
SetModelPropertiesFromView(loanModel, _View, _DataService);
_DataService.InsertLoan(loanModel);
}
}
Now its working but my worry is that here I'm not using the injected instance through the constructor rather newing a child object which creates a dependency. Can anybody propose a better design to solve this issue please?
OK, if I understand correctly, your IDataService interface has specific methods for saving your concrete classes that implement IBaseRecover, but to call the correct save method, you need to know the concrete type of IBaseRecover. Why not push the save responsibility into the concrete implementations of IBaseRecover because they know best which method should be called. You could do this like follows:
interface IBaseRecover{
void Save();
....
}
class LoanRecovery : IBaseRecover {
private IDataService _dataService;
LoadRecovery(IDataService dataService){
_dataService = dataService;
}}
void Save(){
_dataService.InsertLoan(this);
}
}
OK, here's another thought based on your comment. I think the complexity here comes from the fact that you are using a view that can represent three different types of models, and even though they all derive from the same base class, your view has inputs that are specific to each implementation. That's fine, but I think you'd benefit from a different variation of the MVP pattern. Martin Fowler has since broken up the MVP pattern into Supervising Contoller and Passive View. I think Passive View would serve you well here. In that case, your view would expose the values of it's input elements as properties so that the Presenter could get Recovery properties such as IssueDate and Amount without have to know about the view components. So the code for the Insert Action on the view might look something like the following:
public decimal Amount{
get{
return Convert.ToDecimal(txtAmount.text);
}
}
void btnInsert_Click(Object sender, EventArgs e){
presenter.Insert();
}
Note that it's ok for your view to have an instance of the Presenter. Now the Presenter Insert method might look something like this:
public void Insert(){
if(_view.Type == "Loan"){
var model = new LoadRecovery();
model.IssueDate = _view.IssueDate;
model.Amount = _view.Amount;
_dataService.InsertLoan(model);
}
}
And if you were also first displaying a Recovery to be updated instead of inserted:
public void Show(){
_view.IssueDate = model.IssueDate;
_view.Amount = model.Amount;
}
Good afternoon fellow stackers (or overflowers, whichever you prefer), this is more of a cleanliness and convenience issue than anything else but I can't imagine that I'm the only one who's ever wondered about it so here we go...
I've got a basic OData enabled WCF Data Service class that's using my Entity Framework data context.
[JsonpSupportBehavior]
public class ControlBindingService : DataService<MyDataContext>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
config.DataServiceBehavior.AcceptCountRequests = true;
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
}
protected override MyDataContext CreateDataSource()
{
if (HttpContext.Current == null)
throw new InvalidOperationException("The WCF Data Services implementation must be hosted in IIS.");
string username;
if (HttpContext.Current.User.Identity.IsAuthenticated)
username = HttpContext.Current.User.Identity.Name;
else
{
// The request didn't have user identity, attempt to find UserName in the
// request header before returning 401 to the caller.
if (!String.IsNullOrEmpty(HttpContext.Current.Request.Headers["UserName"]))
{
username = HttpContext.Current.Request.Headers["UserName"];
// REVIEW: We should validate user before passing it to the datacontext.
}
else
throw new DataServiceException(401, "Client did not pass required authentication information.");
}
return MyDataContext.GetInstance(username);
}
[WebGet]
public List<DailyKeyPerformanceIndicator> GetResourceKPIs(
int resourceId, string jsonStart, string jsonEnd, int scenarioId)
{
DateTime start = jsonStart.DeserializeJson<DateTime>();
DateTime end = jsonEnd.DeserializeJson<DateTime>();
if (scenarioId < 1)
{
scenarioId = CurrentDataSource.GetScenarios()
.Single(s => s.IsProduction).ScenarioID;
}
return CurrentDataSource.GetDailyResourceKPI(
scenarioId, start, end, resourceId);
}
}
The data context is just a standard (code-first) DbContext implementation with properties exposing the entity sets, etc..
However, we also have methods on there to expose some tables that we wanted to enforce some constraints upon. Specifically (see code below), we want to know what the caller wants to use the data for so we can return only the appropriate results. For example, if the caller wants to get rows from the employees table--they may want to get all rows, or only rows that they have update privileges for.
[Serializable]
public partial class MyDataContext : DbContext
{
static MyDataContext()
{
Database.SetInitializer<MyDataContext>(null);
}
public MyDataContext()
: base("name=MyDBString")
{ }
// Standard table properties...
public DbSet<User> Users
{
get { return this.Set<User>(); }
}
public DbSet<UserSetting> UserSettings
{
get { return this.Set<UserSetting>(); }
}
public DbSet<SettingDefinition> SettingDefinitions
{
get { return this.Set<SettingDefinition>(); }
}
// Restricted table methods...
public DbSet<Client> GetClients(
DatabasePermissions perms = DatabasePermissions.Select)
{
// getPermissibleSet is a method in a helper class that does some
// magical querying and produces a filtered DbSet.
return getPermissibleSet<Client>(perms);
}
public DbSet<Employee> GetEmployees(
DatabasePermissions perms = DatabasePermissions.Select)
{
// getPermissibleSet is a method in a helper class that does some
// magical querying and produces a filtered DbSet.
return getPermissibleSet<Employee>(perms);
}
}
Now to the root of the issue... What I'd like to avoid having to do is writing a [WebGet] for each and every "restricted table method" on my data context. The reason is really nothing more than redundancy--the [WebGet] method would end up being a direct pass-through to the data context.
So in summary, I'd say what I'm basically looking to do is to mark methods from my data context class that WCF will expose in the same way it does for my DbSet properties. Any takers?
Thanks! J
This is an interesting problem. I'm trying to do similar things. This is kind of throwing a dart here but have you tried something like this? You should probably separate the generics out so you don't create a unique context with each type, but it seems like you should be able to get rid of the duplicate code with generics.
[Serializable]
public partial class MyDataContext<T> : DbContext where T : class
{
static MyDataContext()
{
Database.SetInitializer<MyDataContext>(null);
}
public MyDataContext()
: base("name=MyDBString")
{ }
// Standard table properties...
public DbSet<T> SettingDefinitions
{
get { return this.Set<T>(); }
}
// Restricted table methods...
public DbSet<T> GetClients(
DatabasePermissions perms = DatabasePermissions.Select)
{
// getPermissibleSet is a method in a helper class that does some
// magical querying and produces a filtered DbSet.
return getPermissibleSet<T>(perms);
}
}
I'm new to DDD, and I'm trying to apply it in real life. There is no questions about such validation logic, as null check, empty strings check, etc - that goes directly to entity constructor/property. But where to put validation of some global rules like 'Unique user name'?
So, we have entity User
public class User : IAggregateRoot
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
// other data and behavior
}
And repository for users
public interface IUserRepository : IRepository<User>
{
User FindByName(string name);
}
Options are:
Inject repository to entity
Inject repository to factory
Create operation on domain service
???
And each option more detailed:
1 .Inject repository to entity
I can query repository in entities constructor/property. But I think that keeping reference to repository in entity is a bad smell.
public User(IUserRepository repository)
{
_repository = repository;
}
public string Name
{
get { return _name; }
set
{
if (_repository.FindByName(value) != null)
throw new UserAlreadyExistsException();
_name = value;
}
}
Update: We can use DI to hide dependency between User and IUserRepository via Specification object.
2. Inject repository to factory
I can put this verification logic in UserFactory. But what if we want to change name of already existing user?
3. Create operation on domain service
I can create domain service for creating and editing users. But someone can directly edit name of user without calling that service...
public class AdministrationService
{
private IUserRepository _userRepository;
public AdministrationService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public void RenameUser(string oldName, string newName)
{
if (_userRepository.FindByName(newName) != null)
throw new UserAlreadyExistException();
User user = _userRepository.FindByName(oldName);
user.Name = newName;
_userRepository.Save(user);
}
}
4. ???
Where do you put global validation logic for entities?
Thanks!
Most of the times it is best to place these kind of rules in Specification objects.
You can place these Specifications in your domain packages, so anybody using your domain package has access to them. Using a specification, you can bundle your business rules with your entities, without creating difficult-to-read entities with undesired dependencies on services and repositories. If needed, you can inject dependencies on services or repositories into a specification.
Depending on the context, you can build different validators using the specification objects.
Main concern of entities should be keeping track of business state - that's enough of a responsibility and they shouldn't be concerned with validation.
Example
public class User
{
public string Id { get; set; }
public string Name { get; set; }
}
Two specifications:
public class IdNotEmptySpecification : ISpecification<User>
{
public bool IsSatisfiedBy(User subject)
{
return !string.IsNullOrEmpty(subject.Id);
}
}
public class NameNotTakenSpecification : ISpecification<User>
{
// omitted code to set service; better use DI
private Service.IUserNameService UserNameService { get; set; }
public bool IsSatisfiedBy(User subject)
{
return UserNameService.NameIsAvailable(subject.Name);
}
}
And a validator:
public class UserPersistenceValidator : IValidator<User>
{
private readonly IList<ISpecification<User>> Rules =
new List<ISpecification<User>>
{
new IdNotEmptySpecification(),
new NameNotEmptySpecification(),
new NameNotTakenSpecification()
// and more ... better use DI to fill this list
};
public bool IsValid(User entity)
{
return BrokenRules(entity).Count() == 0;
}
public IEnumerable<string> BrokenRules(User entity)
{
return Rules.Where(rule => !rule.IsSatisfiedBy(entity))
.Select(rule => GetMessageForBrokenRule(rule));
}
// ...
}
For completeness, the interfaces:
public interface IValidator<T>
{
bool IsValid(T entity);
IEnumerable<string> BrokenRules(T entity);
}
public interface ISpecification<T>
{
bool IsSatisfiedBy(T subject);
}
Notes
I think Vijay Patel's earlier answer is in the right direction, but I feel it's a bit off. He suggests that the user entity depends on the specification, where I belief that this should be the other way around. This way, you can let the specification depend on services, repositories and context in general, without making your entity depend on them through a specification dependency.
References
A related question with a good answer with example: Validation in a Domain Driven Design.
Eric Evans describes the use of the specification pattern for validation, selection and object construction in chapter 9, pp 145.
This article on the specification pattern with an application in .Net might be of interest to you.
I would not recommend disallowing to change properties in entity, if it's a user input.
For example, if validation did not pass, you can still use the instance to display it in user interface with validation results, allowing user to correct the error.
Jimmy Nilsson in his "Applying Domain-Driven Design and Patterns" recommends to validate for a particular operation, not just for persisting. While an entity could be successfully persisted, the real validation occurs when an entity is about to change it's state, for example 'Ordered' state changes to 'Purchased'.
While creating, the instance must be valid-for-saving, which involves checking for uniqueness. It's different from valid-for-ordering, where not only uniqueness must be checked, but also, for example, creditability of a client, and availability at the store.
So, validation logic should not be invoked on a property assignments, it should be invoked upon aggregate level operations, whether they are persistent or not.
Edit: Judging from the other answers, the correct name for such a 'domain service' is specification. I've updated my answer to reflect this, including a more detailed code sample.
I'd go with option 3; create a domain service specification which encapsulates the actual logic that performs the validation. For example, the specification initially calls a repository, but you could replace it with a web service call at a later stage. Having all that logic behind an abstract specification will keep the overall design more flexible.
To prevent someone from editing the name without validating it, make the specification a required aspect of editing the name. You can achieve this by changing the API of your entity to something like this:
public class User
{
public string Name { get; private set; }
public void SetName(string name, ISpecification<User, string> specification)
{
// Insert basic null validation here.
if (!specification.IsSatisfiedBy(this, name))
{
// Throw some validation exception.
}
this.Name = name;
}
}
public interface ISpecification<TType, TValue>
{
bool IsSatisfiedBy(TType obj, TValue value);
}
public class UniqueUserNameSpecification : ISpecification<User, string>
{
private IUserRepository repository;
public UniqueUserNameSpecification(IUserRepository repository)
{
this.repository = repository;
}
public bool IsSatisfiedBy(User obj, string value)
{
if (value == obj.Name)
{
return true;
}
// Use this.repository for further validation of the name.
}
}
Your calling code would look something like this:
var userRepository = IoC.Resolve<IUserRepository>();
var specification = new UniqueUserNameSpecification(userRepository);
user.SetName("John", specification);
And of course, you can mock ISpecification in your unit tests for easier testing.
Iām not an expert on DDD but I have asked myself the same questions and this is what I came up with:
Validation logic should normally go into the constructor/factory and setters. This way you guarantee that you always have valid domain objects. But if the validation involves database queries that impact your performance, an efficient implementation requires a different design.
(1) Injecting Entities: Injecting entities can be technical difficult and also makes managing application performance very hard due to the fragmentation of you database logic. Seemingly simple operations can now have an unexpectedly performance impact. It also makes it impossible to optimize your domain object for operations on groups of the same kind of entities, you no longer can write a single group query, and instead you always have individual queries for each entity.
(2) Injecting repository: You should not put any business logic in repositories. Keep repositories simple and focused. They should act as if they were collections and only contain logic for adding, removing and finding objects (some even spinoff the find methods to other objects).
(3) Domain service This seems the most logical place to handle the validation that requires database querying. A good implementation would make the constructor/factory and setters involved package private, so that the entities can only be created / modified with the domain service.
I would use a Specification to encapsulate the rule. You can then call when the UserName property is updated (or from anywhere else that might need it):
public class UniqueUserNameSpecification : ISpecification
{
public bool IsSatisifiedBy(User user)
{
// Check if the username is unique here
}
}
public class User
{
string _Name;
UniqueUserNameSpecification _UniqueUserNameSpecification; // You decide how this is injected
public string Name
{
get { return _Name; }
set
{
if (_UniqueUserNameSpecification.IsSatisifiedBy(this))
{
_Name = value;
}
else
{
// Execute your custom warning here
}
}
}
}
It won't matter if another developer tries to modify User.Name directly, because the rule will always execute.
Find out more here
In my CQRS Framework, every Command Handler class also contains a ValidateCommand method, which then calls the appropriate business/validation logic in the Domain (mostly implemented as Entity methods or Entity static methods).
So the caller would do like so:
if (cmdService.ValidateCommand(myCommand) == ValidationResult.OK)
{
// Now we can assume there will be no business reason to reject
// the command
cmdService.ExecuteCommand(myCommand); // Async
}
Every specialized Command Handler contains the wrapper logic, for instance:
public ValidationResult ValidateCommand(MakeCustomerGold command)
{
var result = new ValidationResult();
if (Customer.CanMakeGold(command.CustomerId))
{
// "OK" logic here
} else {
// "Not OK" logic here
}
}
The ExecuteCommand method of the command handler will then call the ValidateCommand() again, so even if the client didn't bother, nothing will happen in the Domain that is not supposed to.
in short you have 4 options:
IsValid method: transition an entity to a state (potentially invalid) and ask it to validate itself.
Validation in application services.
TryExecute pattern.
Execute / CanExecute pattern.
read more here
Create a method, for example, called IsUserNameValid() and make that accessible from everywhere. I would put it in the user service myself. Doing this will not limit you when future changes arise. It keeps the validation code in one place (implementation), and other code that depends on it will not have to change if the validation changes You may find that you need to call this from multiple places later on, such as the ui for visual indication without having to resort to exception handling. The service layer for correct operations, and the repository (cache, db, etc.) layer to ensure that stored items are valid.
I like option 3. Simplest implementation could look so:
public interface IUser
{
string Name { get; }
bool IsNew { get; }
}
public class User : IUser
{
public string Name { get; private set; }
public bool IsNew { get; private set; }
}
public class UserService : IUserService
{
public void ValidateUser(IUser user)
{
var repository = RepositoryFactory.GetUserRepository(); // use IoC if needed
if (user.IsNew && repository.UserExists(user.Name))
throw new ValidationException("Username already exists");
}
}
Create domain service
Or I can create domain service for
creating and editing users. But
someone can directly edit name of user
without calling that service...
If you properly designed your entities this should not be an issue.