According to the MassTransit creators, having class-based inheritance is not considered as good practice - https://masstransittemp.readthedocs.io/en/latest/overview/inheritance.html
I honestly can't understand why. Here is my simplified real-life scenario: Imagine I have an insurance microservice which is dealing with policies. I know in advance that all the policy-related events are going to have some mandatory fields like: id, product, etc.
public class InsurancePolicyEvent
{
Guid EventId { get; set;}
Guid PolicyId { get; set; }
InsuranceProduct Product { get; set;}
}
Why can't I simply leverage inheritance here and do not repeat my self in the inherited events, like this:
public class PolicyTerminated : InsurancePolicyEvent
{
...
}
public class PolicyIssued : InsurancePolicyEvent
{
...
}
To clarify my position, MassTransit recommends the use of interfaces instead of classes, and is perfectly happy with a base type like you've shown above, particularly when it's to enforce fields as a type of event.
Interface-based inheritance is OK, don't be afraid, but don't go nuts.
And right below that, yes, class-based inheritance is discouraged - mainly because developers often do bad things with it. Now, what you've shown above is fine, I see no issues with it.
However, once your InsuranceProduct class starts to evolve, and some expectation of base-class virtual method dispatch behavior begins to creep into the model, that's the path to bad times. And it might not be you, it might be a less experienced developer who was taught OO class design and figured, why not right?
So, just be careful out there :)
Related
I was wondering, should the entities have the capability to save changes to the context? Or have business logic that relates to that particular entity? For example:
ActionResult ResetPassword(UserViewModel viewModel)
{
var user = userCollection.GetUser(viewModel.Username);
user.ResetPassword();
}
where:
class User : Entity
{
public string Password{ get; set; }
public ResetPassword()
{
Password = ""
context.SaveChanges();
}
}
I find this a bit weird since the entity would have a reference to the context. I am not sure whether this would work either - or whether this is recommended. But I want to work on a domain where I do not have to worry about saving changes, at a higher level etc. How can I accomplish this?
Thanks!
Update
I have updated my example - hope its a bit clearer now :)
According to Domain-Driven Design domain objects should have behavior.
You should definately read this book:
I would keep my Entities as POCO's(Plain Old Class Objects, classes with only properties) and have a Repositary do methods like Insert / Update.
I can keep my Entities in a separate class library and use it in different places ( even in a different project), with a different Repository implementation.
In this Tutorial It is nicely explained, how to do a Repositary & Unit Of Work Patterns on an MVC project which uses Entity Framework
You may want to consider the UnitOfWork pattern between your controller and your entities.
http://martinfowler.com/eaaCatalog/unitOfWork.html
I'm very new to RavenDB and MVC3, in particular the usage (not concept) of IoC. So just to warn you that this will sound like a very beginner question.
In summary:
I have a domain model, let's say it's
public class Goose
Within this class I might have a more complex object as a property
public Beak beak { get; set; }
In RavenDB we are rightly encouraged to [JsonIgnore] this property or not have it at all and instead have a reference identifier, like
public String beakId { get; set; }
Somwhere along the way in my MVC3 application I will want to view the Goose and I might want to display to the user, something about the Goose and it's Beak (should that be Bill?). So yeah I need a view model right?
public class GooseModel
{
public String BeakColour { get; set; }
public String BeakLength { get; set; }
...etc
}
Right, so assuming I have some GooseRepository and some BeakRepository here's the simple question....
I'm in the GooseController class and I'm loading a Goose to view. At what point do I use the BeakRepository and who should know about it? The GooseController knows about the GooseRepository and is loading the Goose by id. At this point we could have some property inside the Goose class which represents the whole Beak, but I don't really want to inject the BeakRepository into the GooseRepository do I? Ok, so perhaps when I create the GooseModel from the Goose I've found I could get the GooseModel properties for the BeakColour and BeakLength, how? Well I like AutoMapper, so perhapds my Map For the GooseModel from Goose is using the BeakRepository to find the Beak and then extract the two Beak properties to populate the GooseModel fields.. this too seems wrong... so what's left? The GooseController.. should the Goose controller know about the BeakRespository and then find and set the BeakColour and BeakLength!? that certainly seems completely wrong too..
So where does it get done? the Controller, the domain object, the mapper or somewhere else? Perhaps I should have a partial view of Type Beak which is used within the Goose view?..
I tend to consolidate this kind of logic into a service/business layer (GooseService) that i then inject into the controller. your service layer might take a GooseRepository and a BeakRepository, and return a resolved object that has mapped the GooseViewModel together.
Uhm,... reading your question I strongly suggest you forget about the Service-Layer and the Repository-Layer. If you don't have really good reasons to keep them (testing is not one of them since RavenDB has an EmbeddableDocumentStore, which is fast and easy) pull them in order to take advantage of some very nice features of RavenDB.
I've actually written a post about why I think you should generally avoid these layers:
http://daniellang.net/keep-your-code-simple/ It is about NHibernate, but concepts apply here as well.
Whether you should denormalize the BeakColor and BeakLength property into your Goose-document depends on your applications need. If you feel comfortable with the term "aggregate root", then the rule of thumb is that these generally are your documents. If you're not sure whether denormalization should be applied, avoid it, and use .Include(goose => goose.Beak) instead when loading your Goose.
Please let me know if that makes sense to you.
Lets take a hypothetical project such as a student enrollment system for a music school.
Within the system there needs to exist a way to enter student data for a new student interested in receiving instruction at this school and we can assume that students may have access to this functionality through a web site.
Part of the enrollment process asks the student the type of instrument for which she would like to receive instruction.
As a result of entering information about her preferred musical instrument the behavior will be to assign a default instructor who is assigned to that group of instruments.
Before completing the enrollment request the student will be also be able to change the assigned instructor to different instructor who also is listed as able to give instructed for her selected instrument.
Given this description, the part I'm having a little trouble with is how manage the list of possible instructors out of the ones who are able to give instruction for particular instrument in terms of choosing a default instructor for a new student first, and secondly how to use this same data when it comes time to validate the selected instructor before an enrollment is submitted.
Other technical constraints are that up to this point I've been using a self validating technique very similar to the one presented in Jimmy Nilsson's book Applying Domain-Driven Design and Patterns so it is mainly unclear to me the best way to go about continuing following self validating techniques when access to external data is necessary which I would normally see as outside of the scope of the entity being tested for validity.
The options I'm aware of:
Move validation outside of the entity itself. Perhaps validation is moved into a set of services or a single service per entity which analyses current state of the whole entity and deems it valid or not and provides for domain events or other value objects to be emitted that give more insight about what validation rules have been broken. In this case I'm still a bit uneasy about how the service would get access to the necessary information about instructors
Allow for access to a instructor repository from necessary entities that are attempting to perform this validation.
Create a service that allows access to a list of instructors by instrument category. Alternatively create two separate services, one that returns whether a given instructor is in the list of instructors for a given category, and another which returns the default instructor for a given category.
Load a list of instructor value objects within my aggregate root (likely student, or a student enrollment request) that can be used for validation either by the aggregate root or entities contained within the root.
In either of the first two cases above it seems like the use of a instructor repository would be overkill because I don't need to access an aggregate root that represents an instructor but instead in my case I would see the instructor as a value object that describes the student enrollment request and having a repository spit back value objects seems to be blurring the lines of what a repository is supposed to be doing. For the last two options it seems wrong two allow access to data from a service or a factory in the case of option 4 since aren't repositories supposed to be in charge of data access such as this? And if repositories are the right place for this logic where are the appropriate places to access or store references to repositories? I've been convinced that there are reasons not to access repositories directly within any entity or value object that makes up the model so I'm wondering if this is a case where I may have to bend on that assumption. I should also mention that I'm pretty new to DDD and I'm just now encountering some of my head scratching moments and attempting not to box myself in so any knowledgeable input on this topic would be valuable.
Move validation outside of the entity itself.
One instructor shouldn't know about all other instructors. Validation against set of instructors isn't responsibility of one particular instructor.
Allow for access to a instructor repository from necessary entities that are attempting to perform this validation.
Domain model should be persistence ignorant. Need to break that indicates flaws in Your model.
Create a service that allows access to a list of instructors by instrument category.
This bit of information reveals lack of aggregate root - I would call it InstrumentClass.
Introducing that into Your model would solve some of Your issues. InstrumentClass would hold available instructors that teaches particular instrument.
Next thing You need to figure out is how to describe properly student that is assigned to class. Unfortunately I can't name it at the moment (maybe Participation?). But that entity would be used for InstrumentClass to figure out which instructors are too busy.
Here's my "free-style" (just to show what I see) on modeling Your domain:
using System;
public class Main{
public Main(){
var instructor = new Instructor();
var instrument = new Instrument("saxaphone");
var saxaphoneClass = new InstrumentClass(saxaphone,teacher);
var me=new Person("Arnis");
//here, from UI, I can see available classes, choose one
//and choose according instructor who's assigned to it
var request=me.RequestEnrollment(saxaphoneClass, instructor);
saxaphoneClass.EnrollStudent(request);
}
}
public class Person{
public IList<EnrollmentRequest> EnrollmentRequests { get; private set; }
public EnrollmentRequest RequestEnrollment
(InstrumentClass instrumentClass,Instructor instructor){
if (!instrumentClass.IsTeachedByInstructor(instructor))
throw new Exception("Instructor does not teach this music instrument");
var request=new EnrollmentRequest(this,instrumentClass,instructor);
EnrollmentRequests.Add(request);
return request;
}
}
public class EnrollmentRequest{
public Person Person{ get; private set; }
public InstrumentClass InstrumentClass { get; private set; }
public Instructor Instructor{ get; private set; }
}
public class InstrumentClass{
public void EnrollStudent(EnrollmentRequest request){
var instructor=request.Instructor;
var student=new Student(request.Person);
var studies=new Studies(this,student,instructor);
//TODO: this directiveness isn't good
//student/instructor should listen for class events themselves
//and class should listen if by any reason instructor or student cannot
//participate in studies
student.EnrollInClass(studies);
instructor.AssignStudent(studies);
Studies.Add(studies);
}
public bool IsTeachedByInstructor(Instructor instructor){
return Instructors.Contains(instructor);
}
public InstrumentClass
(Instrument instrument, params Instructor[] instructors){
Instrument=instrument; Instructors=instructors.ToList();
}
public IList<Instructor> Instructors{get;private set;}
public IList<Studies> Studies { get; private set; }
public Instrument Instrument { get; private set; }
}
public class Studies{
public Student Student { get; private set; }
public Instructor Instructor { get; private set; }
public InstrumentClass InstrumentClass { get; private set; }
}
public class Student{
}
public class Instructor{
}
public class Instrument{
}
My answer does not cover the detailed implementation / code as it seems that you are using this as an exercise to learn more about DDD.
Remember that in most cases you'll not be able to get the model right the first time and need to evolve the model. As you “play with it” certain rigid parts will become more flexible to change. (Like a gardening glove as per Eric's analogy). As you gain new insights into the domain, you'll find that you need to introduce new concepts into your model. Using “simple examples” has dangers for example they can lack depth. But simple examples are sometimes needed to get the hang of DDD and fortunately we can evolve the example too ;)
One thing I've heard Eric Evans mention was that if the domain does not feel right or you have trouble expressing something in a model you might be missing a concept. Naturally if you have the concepts in your domain you can “get a feeling” or find a natural place where validation will occur.
Having set the context I thus have a proposition as follow:
Enterprise Patterns and MDA has some complex patterns but the idea you can take away is the CapacityManager of the Inventory archetype as guidance. Unfortunately the model on pg 278 is not available online but have a look at the ServiceInventory archetype.
The instructors are selling their services to students. (Instructors get a salary last time I checked :). If I were to map your example to the Inventory archetype for ideas I would use:
Inventory - List of instruments/courses
ServiceType - Instrument / Course details, start end etc
ServiceInventoryEntry - Instrument + places available (uses capacity manager)
ServiceInstance - Enrollment - place in class (Scheduled, Booked, Canceled, Completed)
CapacityManager (used by ServiceInventoryEntry)
ReservationRequest - Enrollment request
I think the key concept added is the CapacityManager: You can call the ServiceInventoryEntry::getCourses() method which will use the CapacaityManager (service or class) to show you / calculate the available teachers or return the default one. Thus, call it multiple times depending on the context: Default or Propose a list of available places/seats/instructors.
With this model you should be able to find natural place (where and when) to validate. The guidance from Streamlined Object Modeling is to put validation where the data is. Not to be taken as a hard rule but there is a natural tendency for objects to have the proper concerns and data grouped together. For example the capacity manager knows about enrollments and instruments. (From MDA - CapacityManger: Manages utilization of capacity by releasing ServiceInstances)
To get your aggregates see what transactions / changes you'll do so that you can ensure they enforce the invariants (rules). In your example I would make ServiceType(Course) a value object, ServiceInventoryEntry and ReservationRequests aggregate roots. (Depends on how complex you want to take your rules). You can also add Students and Teachers as parties as per the MDA book. I tend to use repositories to get hold of my aggregates and then also rely on inversion of control as per Jimmy's book you referenced.
The reason I like the MDA patterns is that it makes me think of use cases and model concepts that I or the business would not have imagined. But, be careful to only model what you need since the MDA patterns can be big and even enticing. The good thing is that they are designed to be modular or "down scalable".
So in short:
- Your aggregate roots should ensure your domain is in a valid state (Rules / Invariants)
- Put the validation where the data is. Your model will guide your.
If you read this article on Validation with the Data Annotation Validators, it shows that you can use the MetadataType attribute to add validation attributes to properties on partial classes. You use this when working with ORMs like LINQ to SQL, Entity Framework, or Subsonic. Then you can use the "automagic" client and server side validation. It plays very nicely with MVC.
However, a colleague of mine used an interface to accomplish exactly the same result. it looks almost exactly the same, and functionally accomplishes the same thing. So instead of doing this:
[MetadataType(typeof(MovieMetaData))]
public partial class Movie
{
}
public class MovieMetaData
{
[Required]
public object Title { get; set; }
[Required]
[StringLength(5)]
public object Director { get; set; }
[DisplayName("Date Released")]
[Required]
public object DateReleased { get; set; }
}
He did this:
public partial class Movie :IMovie
{
}
public interface IMovie
{
[Required]
object Title { get; set; }
[Required]
[StringLength(5)]
object Director { get; set; }
[DisplayName("Date Released")]
[Required]
object DateReleased { get; set; }
}
So my question is, when does this difference actually matter?
My thoughts are that interfaces tend to be more "reusable", and that making one for just a single class doesn't make that much sense. You could also argue that you could design your classes and interfaces in a way that allows you to use interfaces on multiple objects, but I feel like that is trying to fit your models into something else, when they should really stand on their own. What do you think?
I like your interface approach as it allows you to define a contract for your model which you can use to adapt your ORM generated classes to. That would allow you to decouple your app from the ORM framework and get more use out of the MetadataType interface as it serves as data validation metadata as well as a contract for your model. You could also decorate your interface with serialization attributes for use in WCF gaining more use out of the interface. I followed a few early blogs that recommended creating a metadata class but again I think the interface solution is a nice idea.
If those two options are the two I am presented with, I would personally probably choose the interface way, simply because I think it looks cleaner. But this is entirely based on personal taste - I don't know enough about the inner workings of .NET to say for sure, but I don't know any case where the actual functionality of the two approaches would differ.
On the other hand, a much better approach would be to use Data Transfer Objects (DTO's) for sending data back and forth, and have the validation requirements on them. That is, instead of requiring that the Movie object meet all the validation requirements, you require that a MovieInput object meets all those requirements, and then create code to map a correct MovieInput into a Movie. (If you don't want to do that manually, you could use AutoMapper or some other utility).
The concept is basically to have something like a View Model object on the way in just as well as on the way out - I could just as well have let MovieInput be called MovieViewModel and use it for transferring of data both in and out of the server.
I see no functional difference between the two approaches. I'm not sure reusability is really important here, given that validation will most often be on "one-off" ViewModels that probably won't get much, if any, reuse.
OK, having tried my first TDD attempt, it's time to reflect a little
and get some guidance, because it wasn't that successful for me.
The solution was partly being made with an existing framework, perhaps
making TDD less ideal. The part that seemed to give me the biggest
problem, was the interaction between the view and controller. I'll
give a few simple examples and hope that someone will tell me what I
can do better wrong.
Each view's interface inherits from a base interface, with these
members (there are more):
public interface IView
{
void ShowField(string fieldId)
void HideField(string fieldId)
void SetFieldVisibility(string fieldId, bool visible)
void DisableField(string fieldId)
void ShowValidationError(string fieldId)
...
}
The interface for a concrete view, would then add members for each
field like this
public interface IMyView : IView
{
string Name { get; set; }
string NameFieldID { get; }
...
}
What do you think of this? Is inheriting from a common interface a
good or bad idea?
One on the things that gave me trouble was, that first I used
ShowField and HideField and the found out I would rather use
SetFieldVisiblity. I didn't change the outcome of the method, but I
had to update my test, which I seem should be necessary. Is having
multiple methods doing the same thing, a bad thing? On one hand both
methods are handy for different cases, but they do clutter the
interface, making the interface more complex than it strictly have to be.
Would a design without a common interface be better? That would remove
the fieldID, I don't why, but I think the fieldID-thing smells, I
might be wrong.
I would only make the Show and Hide methods, when needed, that is if
they would be called by the controller. This would be a less generic
solution and require more code in the view, but the controller code
would be a bit more simple.
So a view interface might look like this:
public interface IMyView
{
void ShowName()
void HideName()
string Name { get; set; }
int Age { get; set; }
}
What do you want to test? Whether Show* will make an widget in the UI visible? What for?
My suggestion: Don't try to figure out if a framework is working correctly. It's a waste of time. The people who developed the framework should have done that, so you're duplicating their work.
Usually, you want to know if your code does the right thing. So if you want to know if you are calling the correct methods, create mockups:
public class SomeFrameworkMockup extends SomeFramework {
public boolean wasCalled;
public void methodToTest() {
wasCalled = true;
}
}
Build the UI using the mockups.
The second thing to test is whether your algorithms work. To do that, isolate them in simple helper objects where you can all every method easily and test them with various inputs.
Avoid the external framework during tests. It only confuses you. When you've built a working product, test that using your mouse. If you find any problems, get to the root of them and only then, start writing tests against the framework to make sure this bug doesn't appear again. But 90% of the time, these bugs will be in your code, too.
At the moment I don't really see the added value of the common interface.
I think a better solution would be to have some properties on the controller class: IsControlXYZVisible. You can then databind the visible property of the control to this property.
And your unit test will test the value of IsControlXYZVisible, which will be easier to acomplish.
I also don't understand why you say you had a bad experience with TDD. I think your application architecture needs more work.
Your question is a little bit obscure for me but the title itself calls for a link :
The Humble Dialog box
And when you ask if it(s bad to have two functions doing the same thing, I say "Yes it's bad".
If one is calling the other, what's the point of having two functions ?
If not, you have a code duplication, that is a bug waiting to sprout whenyou update one and not the other.
In fact there is a valid case where you have two nearly identical functions : one that check its arguments and one that does not but usually only one is public and the other private ...