Is this class structure method correct/desireblable? (MVC/C#) - c#

I'm building a MVC application which is a bit more complex than what I usually do and I want to try a new class structure. Basically theres a lot of reading going on. Just 5-10% of operations will be insert/update against the database.
Because of this, I'm thinking of creating base DTO classes which would be returned from a database layer. Then, business objects would inherit from the DTO class in order to extend the basic structure with all the validation and business rules.
Example:
namespace Project.DTO
{
public class Employee
{
public string Name;
public string Surname;
...
}
}
namespace Project
{
public class Employee : Project.DTO.Employee
{
public bool IsValid()
{
...
}
}
}
Is this a good approach? What I haven't thought off yet is how to use them inside the MVC, as the "correct" way would be to implement model classes. I believe I could create model classes that inherited from the DTO objects as well... but I'm unsure.
I would also need a way to handle all validation functions with some kind of Interface, as to avoid repeating to much generic code on the GUI.
Thanks in advance!

I would probably use a completely different approach. My primary thoughts are these:
I would like looser coupling between the classes, so I would not have my model classes inherit from my DTO objects
I would probably not include validation logic in my model classes
This would lead to the following structure to start with:
namespace Project.DTO
{
public class Employee
{
public string Name;
public string Surname;
...
}
}
namespace Project
{
public class Employee
{
public string Name { get; set; }
public string Surname { get; set; }
}
}
When it comes to the validation logic, I would make an interface for the validation logic, that is injected into the Emplyee class:
public interface IValidator<T>
{
bool IsValid(T objectToInspect);
}
public class Employee
{
private readonly IValidator<Employee> validator;
public Employee(IValidator<Employee> validator)
{
this.validator = validator;
}
public string Name { get; set; }
public string Surname { get; set; }
public bool IsValid()
{
return validator.IsValid(this);
}
}
This opens up your design for a whole range of features, including using IoC containers and better support for testing.

What if validation has to check with a rule whose parameters must come from database? Your entity would not have a knowledge and the way to access that parameter.
Creating Model/ViewModel is good but validation usually require more complex logic which would warrant dedicated classes - so I would not normally implement IsValid on my entity.
However, you can use System.Component.DataAnnotation validation attributes against simple properties of your entities.

Related

Mocking domain entity class' properties in unit tests: methods, abstract classes or virtual properties? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I have a class that represents a domain entity and this class does not implement any interfaces. Let's consider something as simple as:
public class DomainEntity
{
public DomainEntity(string name) { Name = name; }
public string Name { get; private set; }
}
I have some other class that I'm testing. It has a method that accepts my DomainEntity as a parameter and this method accesses the Name property. For example:
public class EntityNameChecker : IEntityNameChecker
{
public bool IsDomainEntityNameValid(DomainEntity entity)
{
if (entity.Name == "Valid") { return true; }
return false;
}
}
I have to mock my DomainEntity for my test. I'm using NSubstitute as my mocking library (it does not allow mocking non-virtual/non-abstract properties).
So, without adding interfaces (a-la IDomainEntity) I have three options for mocking the property value left.
Make the Name property virtual:
public class DomainEntity
{
public DomainEntity(string name) { Name = name; }
public virtual string Name { get; }
}
The downside here is that I can no longer make my DomainEntity class sealed, which means that any consumer can inherit from it and override my Name property.
Create an abstract "base" class and use the base class type as a parameter type:
public abstract class DomainEntityBase
{
protected abstract string Name { get; private protected set; }
}
public sealed class DomainEntity : DomainEntityBase
{
public DomainEntity(string name) { Name = name; }
protected override string Name { get; private protected set; }
}
public class EntityNameChecker : IEntityNameChecker
{
public bool IsDomainEntityNameValid(DomainEntityBase entity)
{
if (entity.Name == "Valid") { return true; }
return false;
}
}
The downside here is over-complication. And this basically turns the abstract class into an interface of some sort.
Instead of accessing the Name property directly, turning Name getter into a method call to get the value (we can even go as far as making the method internal and using InternalsVisibleTo attribute to make the method visible to our test assembly):
[assembly: InternalsVisibleToAttribute("TestAssembly")]
public sealed class DomainEntity
{
private string _name;
public DomainEntity(string name) { _name = name; }
public string Name => GetName();
internal string GetName()
{
return _name;
}
}
The downside here is... Um, more code, methods, more complication (and it's not immediately obvious why it's coded this way).
My question is: is there a "preferred" way of doing that? Why is it preferred?
Edit:
The reason I don’t want to simply use the instance of the class in my tests is the fact that there might be additional logic in the constructor. If I break the constructor it’s going to break all dependent tests (but it should break only the tests testing DomainEntity).
I could extract an interface and be done with it. But I prefer to use interfaces to define behaviors. And these classes have none.
I could extract an interface and be done with it. But I prefer to use interfaces to define behaviors. And these classes have none.
You might be making life unnecessarily difficult for yourself by avoiding interfaces here. If you truly want to "mock" the domain entities (meaning, replace production behavior with test-specific behavior), I think an interface is the way to go. However, you specifically said these classes have no behavior, so read on...
The reason I don’t want to simply use the instance of the class in my tests is the fact that there might be additional logic in the constructor. If I break the constructor it’s going to break all dependent tests (but it should break only the tests testing DomainEntity).
It sounds like you don't really need mocking (as I defined it above)--you just need a maintainable way to instantiate test instances.
To solve that problem, you could introduce a builder to construct instances of DomainEntity. The builder will serve as a buffer or abstraction between your tests and the entity constructor. It can supply sane default values for any constructor arguments a particular test doesn't care about.
Using the classes you defined in your question as a starting point, let's assume you have a test like this (using xUnit syntax):
[Fact]
public void Test1() {
var entity = new DomainEntity("Valid");
var nameChecker = new EntityNameChecker();
Assert.True(nameChecker.IsDomainEntityNameValid(entity));
}
Now, maybe we want to add a new required property to the domain entity:
public sealed class DomainEntity {
public string Name { get; private set; }
public DateTimeOffset Date { get; private set; }
public DomainEntity(string name, DateTimeOffset date) {
Name = name;
Date = date;
}
}
The new constructor argument breaks the test (and probably lots of other tests).
So we introduce a builder:
public sealed class DomainEntityBuilder {
public string Name { get; set; } = "Default Name";
public DateTimeOffset Date { get; set; } = DateTimeOffset.Now;
public DomainEntity Build() => new DomainEntity(Name, Date);
}
And modify our test slightly:
[Fact]
public void Test1()
{
// Instead of calling EntityBuilder's constructor, use DomainEntityBuilder
var entity = new DomainEntityBuilder{ Name = "Valid" }.Build();
var nameChecker = new EntityNameChecker();
Assert.True(nameChecker.IsDomainEntityNameValid(entity));
}
The test is no longer tightly coupled to the entity's constructor. The builder provides sane defaults for all properties, and each test provides only the values that are relevant to that specific test. As a bonus, methods (or extension methods) can be added to the builder to help set up complex scenarios.
There are libraries that can help solve this sort of problem. I've used Bogus in a few different projects. I think AutoFixture is a popular option, but I haven't used it myself. A simple builder is easy to implement, so I recommend starting with a home-brew implementation, and adding a 3rd-party library only if the home-brew implementation becomes too tedious or complicated to maintain. Because the builder is an abstraction itself, it will be easy to replace its implementation with one based on a library if/when the time comes.
I have to mock my DomainEntity for my test.
Why?
This, where your approach is gone in the "difficult" direction.
DomainEntity has a constructor which accepts name, so you can use it to setup instance for the test.
[Theory]
[InlineData("Valid", true)]
[InlineData("Not valid", false)]
public void ShouldValidateName(string name, bool expected)
{
var entity = new DomainEntity(name);
var isValid = new EntityNameChecker().IsDomainEntityNameValid(entity);
isValid.Should().Be(expected); // Pass
}
Mock only dependencies which makes tests slow or very very very very complicated to setup.
For example slow tests are usually tests which touches external resources (webservice, database, filesystem etc.).

How to abstract Entity Framework model properties

I have a model that looks like this :
public class Task : ITask
{
public int DocumentId { get; set; }
public virtual Document Document { get; set; }
public TaskType TaskType { get; }
public string Value { get; }
}
Now, this class is directly registered as a DbSet in the DbContext.
This means that the Document property must be of concrete type. I want to make this code easily testable, so I want to have the property as an interface which is required by the ITask interface. What is the general way to approach this problem?
One way that comes to my mind is to put all such classes in a separate assembly but that seems a bit off.
Edit: The ITask interface is defined in a different assembly so it should not know about the Document type.
I would use EF models only for the data access layer and create a separate model for the business layer. The data access layer would be responsible for mapping the EF model to the business layer model and hand it to the business layer.
The business layer model can then also be immutable, which can have advantages. Also you can require all the properties to be e.g. not-null in you constructor and you can then rely on this throughout the whole business layer.
Of course you could argue that it's almost twice as much code to write. That's true, but IMO it results in cleaner code and therefore this is my preferred approach.
Interfaces can have properties defined in them, So your ITask can specify the document, like this:
public interface ITask {
Document Document { get; set; }
}
But you also say that you want the Document property as an interface and this becomes tricky as you need a concrete type in the Task class. Generic interfaces will help here.
// The interfaces
public interface ITask<TDocument> where TDocument : IDocument, new() {
TDocument Document { get; set; }
}
public interface IDocument {
int Number { get; set; } // Example property
}
//The classes
public class Document : IDocument{
public int Number { get; set; } // Example property
}
public class Task : ITask<Document> {
public Document Document { get; set; }
}
// See if it works
public class Test {
private Task myTask = new Task();
public void TestMethod() {
myTask.Document.Number = 1;
}
}
Remember, use the concrete types in DBContext.
As to where the interfaces should be located, same assembly or their own, there's quite a few viewpoints on that. Personally, I put them in their own assembly away from the implementing classes. This question is worth a read:
Should I have a separate assembly for interfaces?
One more comment, the class name Task is used in the .Net threading library, so maybe worth thinking about changing it to avoid potential confusion.

Best way to add behaviors based on type

I have a company entity
public class Company : Entity<Company>
{
public CompanyIdentifier Id { get; private set; }
public string Name { get; private set; }
..............
..........
}
A company can be a agent or supplier or both or none. (There are more types) Its behaviour should be change based on types. Agent can get commission and supplier is able to invoice.
What will be the best way to design the entity or entities or value objects? I have an option to add some boolean types and check those values inside methods,
public class Company : Entity<Company>
{
public CompanyIdentifier Id { get; private set; }
public string Name { get; private set; }
public bool IsAgent { get; private set; }
public bool IsSupplier { get; private set; }
..........
public void Invoice()
{
if(!IsSupplier)
{
throw exception.....;
}
//do something
}
public void GetCommission(int month)
{
if(!IsAgent)
{
throw exception.....;
}
//do something
}
..........
}
To be honest, I do not like this. Is there any design pattern which might help to overcome this scenerio? What will you do and why to design this scenerio?
Implement interfaces explicitly, then override the cast operator to only cast to that interface when valid.
public class Company : ...., IAgentCompany, ISupplierCompany ... {
public double IAgentCompany.GetCommission(int month) {
/*do stuff */
}
public static explicit operator IAgentCompany(Company c) {
if(!c.IsAgent)
throw new InvalidOperationException();
return this;
}
}
Explicit implementations of interfaces must be called through their interface, not the concrete type:
// Will not compile
new Company().GetCommission(5);
// Will compile
((IAgentCompany)new Company()).GetCommission(5)
But, now we've overloaded the explicit cast operator. So what does that mean? We can't call GetCommission without casting to IAgentCompany, and now we have a guard to prevent that cast for a company that isn't marked as an agent.
Good things about this approach:
1) You have interfaces that define the aspects of different types of companies and what they can do. Interface segregation is a good thing, and makes the abilities/responsibilities of each type of company clear.
2) You've eliminated a check for every function you want to call that is not "global" to all companies. You do one check when you cast, and then as long as you have it in a variable typed as the interface, you can happily interact with it without any further checking. This means less places to introduce bugs, and less useless checks.
3) You are leveraging the languages features, and exploiting the type system to help make the code more bullet-proof.
4) You don't have to write tons of subclasses that implement the various combinations of interfaces (possibly 2^n subclasses!) with NotImplementedExceptions or InvalidOperationException everywhere in your code.
5) You don't have to use an enum or a "Type" field, especially when you are asking to mix and match these sets of abilities (you'd don't just need an enum, but a flag enum). Use the type system to represent different types and behaviors, not an enum.
6) It's DRY.
Bad things about this approach:
1) Explicit interface implementations and overriding explicit cast operators aren't exactly bread and butter C# coding knowledge, and may be confusing to those who come after you.
Edit:
Well, I answered too quickly without testing the idea, and this doesn't work for interfaces. However, see my other answer for another idea.
I would look into separating the implementation for all those types in different classes. You could start doing this by using an enum to represent the company type.
public enum CompanyType
{
Agent = 0,
Supplier
}
public abstract class Company : Entity<Company>
{
public CompanyIdentifier Id { get; private set; }
public string Name { get; private set; }
public CompanyType EntityType { get; private set; }
public abstract void Invoice();
public abstract void GetCommission(int month);
...
This way you get less public properties.
Next, I'd implement specialized classes for supplier and agent (and then for both and none). You can make Company abstract and any specialized methods abstract as well.
This will allow you to separate the distinct behaviors of each type of entity. Comes in handy when you get back to it for maintenance. It also makes the code easier read/understand.
public class SupplierCompany : Company
{
public SupplierCompany()
{
EntityType = CompanyType.Supplier;
}
public override void Invoice()
{...}
public override void GetComission(int month)
{...}
}
public class AgentCompany : Company
{
public AgentCompany()
{
EntityType = EntityType.Agent;
}
public override void Invoice()
{...}
public override void GetComission(int month)
{...}
}
With this you can eliminate testing for various types in methods like Invoice and GetComission.
As with most DDD questions, it usually boils down to Bounded Contexts. I'd guess you're dealing with some distinct bounded contexts here (this is most obvious from your statement "A company can be a agent or supplier or both or none."). In at least one context you need to consider all Company entities equally, regardless of whether they are Agents or Suppliers. However I think you need to think about whether or not your Invoice or GetCommission operations are applicable in this broader context? I'd say those will apply in more specialized contexts, where the distinction between an Agent and a Supplier is much more crucial.
You may be running into trouble because you're trying to create an all encompassing Company entity which is applicable in all contexts... this is almost impossible to achieve without weird code constructs & fighting against the type system (as is being suggested in your other answers).
Please read http://martinfowler.com/bliki/BoundedContext.html
As a rough idea of how your contexts might look:
Broad "Company" Context
{
Entity Company
{
ID : CompanyIdentifier
Name : String
}
}
Specialized "Procurement" Context
{
Entity Supplier
{
ID : CompanyIdentifier
Name : String
Invoice()
}
}
Specialized "Sales" Context
{
Entity Agent
{
ID : CompanyIdentifier
Name : String
GetComission()
}
}
Does it make sense to try and use the same object in both Procurement and Sales contexts? These contexts have very different requirements after all. One of the lessons of DDD is that we split the domain into these bounded contexts, and do no try to make "God" objects which can do everything.

Anybody have a clever way to treat a DTO as more of an OO class?

I have a set of DataContracts that are serialzed through WCF.
Please note this is a very simplified example.
[DataContract]
public class MyData
{
[DataMember]
public List<int> MyList
{
get;
set;
}
}
I would like to use object oriented design so that the server and client aren't creating any unnecessary dependencies. For example, I would like to encapsulate a list so that the user can't directly modify it.
Ideally, I would like the class to look like this if it wasn't a DTO.
public class MyData
{
private List<int> _list = new List<int>();
public IEnumerable<int> MyList
{
get
{
return _list;
}
}
public void AddItem( int value )
{
_list.Add( value );
}
}
I am using the same C# assembly from both the service and the client. So I can add non-DataMember methods, but I'm not sure if that is a good approach. It doesn't smell quite right to me.
Does anybody have a clever way of treating DTO classes more like objects instead of simple serializable structures?
How about having DTO versions of your logic class which are used solely for the purpose of message passing?
That way, you can put all the methods and properties on your logic class as necessary without having to worry about what the user has access to when it's passed over the wire. There are many ways you can go about this, for instance:
you can implement some method on your logic class to return the DTO
public class Player
{
// methods that do interesting things here
...
public string Name { get; set; }
public PlayerDTO ToTransport()
{
return new PlayerDTO { Name = Name, ... };
}
}
[DataContract]
public class PlayerDTO
{
[DataMember]
public string Name { get; set; }
...
}
Or you can implement an explicit/implicit conversion
public class Player
{
// methods that do interesting things here
...
public string Name { get; set; }
}
[DataContract]
public class PlayerDTO
{
[DataMember]
public string Name { get; set; }
...
public static explicit operator PlayerDTO(Player player)
{
return new PlayerDTO { Name = player.Name, ... };
}
}
this lets you cast a Player object to PlayerDTO:
var player = new Player { Name = .... };
var dto = (PlayerDTO) player;
Personally, I do think having DataContract on objects which are for more than service operations is a bit of a smell, just as it would be for ORM column mappings. One somewhat limited way to make these DTOs more like true OO is to have your methods be extension methods of the DTO. You might need to do something creative if the OO version has state that needs to be captured between calls that is not inherent in the DTO object itself, though.
I do not think having methods unadorned by attributes in your DataContract's class necessarily smells. You have your service-oriented concerns on one hand (the operation and data contracts) and your object-oriented concerns on the other. What the client does with the provided data is of no concern to the service. The object-oriented issue you describe really only exists for the client.
If a client obtained Ball data from your service and it wants to Draw() it to the screen, whether or not the Ball class has a Draw() method has nothing to do with the contract between service and client. It is a contract between the api your assembly provides and those that use it. So I say, why not have a method in the assembly that is not an operation/data contract?

Best loose way to get objects with common base class

I struggled to come up with a good title for this question, so suggestions are welcome.
Let's say we have an abstract base class ActionBase that looks something like this:
public abstract class ActionBase
{
public abstract string Name { get; }
public abstract string Description { get; }
// rest of declaration follows
}
And we have a bunch of different actions defined, like a MoveFileAction, WriteToRegistryAction, etc. These actions get attached to Worker objects:
public class Worker
{
private IList<ActionBase> _actions = new List<ActionBase>();
public IList<ActionBase> Actions { get { return _actions; } }
// worker stuff ...
}
So far, pretty straight-forward. Now, I'd like to have a UI for setting up Workers, assigning Actions, setting properties, and so on. In this UI, I want to present a list of all available actions, along with their properties, and for that I'd want to first gather up all the names and descriptions of available actions (plus the type) into a collection of the following type of item:
public class ActionDescriptor
{
public string Name { get; }
public string Description { get; }
poblic Type Type { get; }
}
Certainly, I can use reflection to do this, but is there a better way? Having Name and Description be instance properties of ActionBase (as opposed to statics on derived classes) smells a bit, but there isn't an abstract static in C#.
Thank you!
What you're talking about is creating Metadata for your concrete Action classes to describe them. For the simple case of Name and Description, I recommend the DisplayName and Description attributes like this:
[DisplayName("MyAction Name")]
[Description("My description goes here")]
public class MyAction : ActionBase
{
//Declaration goes here
}
These attributes are defined in System.ComponentModel.
You could add an abstract method to ActionBase which returns an ActionDescriptor, and then you could query each action for its descriptor.

Categories

Resources