Thursday, February 24, 2011
My idea about an ideal Project management system.
Team:
Project management has always been a team effort and a team is composed of individuals. Almost all the project management system focus on the projects, tasks, due-dates etc. But there is least focus on team. I'm of opinion that a project management system must give equal focus to team along with other artifacts. In a team everyone may not have equal skill, there are days when people are absent. So, I think a PMS should make it easy for a project manager to manage by individual.
Social process
Project management is always a social process, and a project management system should be able to consider this fact. As a social process the PMS should meet somewhere near facebook. It is mainly about communication. But, by communication I’m not referring to just the communication between client/customer and the project manager. The communication here considers more dimensions. A team member may want to communicate with other team members; as a team member I may want to share some idea with others. I’d like more control over the privacy and public ness of a message being passed, not just a rudimentary control but rather a bit more elaborated and sophisticated control over the message privacy. Something similar to Facebook walls, inboxes, chats etc.
Version control
A project management system should have some sort of version control over the tasks, bugs etc, (mind you I'm not talking about the version control of codes). Almost every time I do some work on a project, I'll be pulling down the works that assigned to me and create a TO-DO for my personal purpose that I may or may not share with others. I do mark things as done and put some comment, for my personal reference, at end of the day I do select the important ones from my notepad (I generally use notepad, for my To-do) and update the project manager. I think it would be better if the project management software did allow me to create my To-do list and make as many changes as I'd like in the tasks assigned to me, without those changes getting reflected to others. At end of the day I'd select and commit the changes that I want others to see.
So, folks these are the three main things I'd like to have in a project management system, along with other general stuffs. So, in conclusion what I want from software project management is the features of Facebook + Redmine + GIT(git here is not for code revision control, but rather the tasks and activities, as I mentioned earlier), combined together.
Well I think I'm quite lazy(I'm not trying to build these things my self, at least not in a near future), and way too demanding. But then this is the human nature :)
Monday, February 14, 2011
Removing the NInject dependency from the Domain model and Entity Framework classes.
One thing that I really don't like about the implementation is that, now the Model as well as the Datacontext is dependent on the NInject framework. Although I'm beginning to love NInject as a dependency framework, but I think the application as whole should be unaware of an IoC framework (As Nate says it is matter of opinion). Now, lets move ahead and try to remove dependency from the NInject framework.
I will first focus on the Member class, as I cannot specially bear to have a NInject dependency in my Domain model. One cool feature of NInject is that it provides the developers with ways to change the manner in which the dependencies are injected. That means although by default it uses "Inject" attribute we can change that behavior. Since, the name of method "InjectDependency" is quite self explanatory, I think it becomes quite unnecessary to decorate that method with extra attribute whose sole purpose is to point out "hey this method should be used to inject the external dependencies".
Here's how we do it. Below is a NInject heuristic that can decides whether to consider a method as an entry point for dependency injection or not. The decision is made based on a lamda expression.
public class NInjectMemberSelector : NinjectComponent, IInjectionHeuristic { public bool ShouldInject(System.Reflection.MemberInfo member) { return member.MemberType == MemberTypes.Method && _predicate(member); } private readonly Func<MemberInfo, bool> _predicate; public NInjectMemberSelector(Func<MemberInfo, bool> predicate) { _predicate = predicate; } }Now let's create a NInject module that uses this heuristics.
public class InjectAllMethodsNamedInjectDependencyModule : NinjectModule { public override void Load() { var selector = Kernel.Components.Get<ISelector>(); //specify that a method with name "InjectDependency",should be considered as an entry point for Injection. var heuristic = new NInjectMemberSelector(member => member.Name.Equals("InjectDependency")); selector.InjectionHeuristics.Add(heuristic); } }This module now needs to be registered to the NInject Kernel.
IKernel kernel = new StandardKernel(); kernel.Load(new InjectAllMethodsNamedInjectDependencyModule());Now, a simple way to avoid NInject dependency from the DbContext. Let's create an Interface named IInject and a class NInjectAdapter that implements the interface
public interface IInject { void Inject(object objectToInject); } public class NinjectAdapter : IInject { private IKernel _kernel; public NinjectAdapter(IKernel kernel) { _kernel = kernel; } public void Inject(object objectToInject) { _kernel.Inject(objectToInject); } }Now, let's use our custom IInject interface instead of instead of the IKernel
public class NInjectDataContext : DbContext { //modified IKernel to IInject public NInjectDataContext(DbConnection dbconnection, IInject kernel): base(dbconnection) { this.Kernel = kernel; (this as IObjectContextAdapter).ObjectContext.ObjectStateManager.ObjectStateManagerChanged += ObjectStateManagerChanged; } //other thing remains as it is..... //... //modified IKernel to IInject public IInject Kernel { get; private set; } }This is it, we have removed the dependency on NInject from our domain model as well as the DbContext class. Hope this would help someone.
Saturday, February 12, 2011
Entity Framework CTP5 injecting with NInject
Hello, this is Nripendra Nath Newa. This is the first time I'm trying to blog some of my thoughts, and I think it's quite a difficult subject that I've choosen.
Now, that microsoft has made its move towards supporting code-first approach for its ADO.Net Entity Framework, and has released developer's preview CTP5, many developer has been using the framework and giving feedback.
I have been currently trying out to practically implement the DDD approach of software development, using the EF code-first ctp5. After studying few books and blogs on DDD and EF code-first, I'm now all set to get my hands dirty. While implementing the DDD approach, it is quite common to use various services or even repositories(though second one seems to be controversial), inside the domain object. So I was trying to find if EF CTP5 has any support for such dependency injection, but I was quite disappointed to see it did not. After a series of googling I did come across a good enough approach. Although we don't have any control over the object materialization, we do have some control as soon as the object has been materialized. And, it was just fine for me(something is better than nothing). It turned out that using NInject to inject already constructed object is a very trivial task :). Thanks a lot to Nate Kohari, the creator of wonderful NInject.
I know it is enough of ranting, and you may be more interested in looking at some code. So here we go, first a domain model called "Member"
public class Member { //The dependencies private IMemberRepository MemberRepository { get; set; } private IAuthenticationService AuthenticationService { get; set; } public long MemberId { get; set; } public string UserName { get; set; } public string Password { get; set; } public string Email { get; set; } public string FirstName { get; set; } public string LastName { get; set; } //A member must be able to sign in. public IDictionary<string, list<string>> SignIn(bool remember) { var errors = new Dictionary<string, list<string>>(); //Use of injected object var existingMember = MemberRepository.GetSingle(member => member.UserName == this.UserName && member.Password == this.Password); if (existingMember != null) { //Use of injected object AuthenticationService.SignIn(this.UserName, remember); } else { if (!errors.ContainsKey("UserName,Password")) { var errorMessages = new List<string>{WTDErrors.UsernameOrPassword}; errors.Add("UserName,Password", errorMessages); } } return errors; } //end SignIn() //A visitor must be able to register to become a member public IDictionary<string, list<string>> RegisterToBecomeMember() { //even this could be injected, but I'm ok with this for now. var validator = new MemberValidator(MemberRepository); var errors = new Dictionary<string, list<string>>(); //The validator objects will contain all the validation rules, so that the domain model doesn't get cluttered. But still the domain object enforces the business rules. var validationResult = validator.Validate(this); if (validationResult.IsValid) { MemberRepository.Add(this); MemberRepository.Save(); } else { foreach (ValidationFailure failure in validationResult.Errors) { var errorMsg = failure.ErrorMessage; if (!errors.ContainsKey(failure.PropertyName)) { errors.Add(failure.PropertyName, new List<string>{errorMsg}); } else { errors[failure.PropertyName].Add(errorMsg); } } } return errors; } //end RegisterToBecomeMember() }
Leaving all other details aside, the member model is dependent on two external objects, a member-repository, and an authentication service. It is always a good practice to decouple such concerns, from maintainability point of view. A standard way to decouple such external objects is to use dependency injection. The most popular and preferred approach to inject such dependencies would be to use a constructor, for example:
public Member(IMemberRepository memberRepository, IAuthenticationService authenticationService) { this.MemberRepository = memberRepository; this.AuthenticationService = authenticationService; }
But as, discussed earlier it is not possible to change how the objects are materialized in the Entity Framework, so we don't have an option to use the constructor to inject the dependency. Other popular techniques to do dependency injection, are to use property injection or the method injection. In this case I do find method injection more appealing, (note that it is just my personal preference, and property injection is also equally valid approach). So, I'll use a method named "InjectDependencies" as a point to inject the dependencies into the objects.
public InjectDependencies(IMemberRepository memberRepository, IAuthenticationService authenticationService) { this.MemberRepository = memberRepository; this.AuthenticationService = authenticationService; }
Now, NInject has a very easy way to notify that a method or property is injectable. It provides an attribute named "Inject". So, decorating the method "InjectDependencies" with an "Inject" attribute will assure that NInject knows how to inject the dependencies, for example:
[Inject] public InjectDependencies(IMemberRepository memberRepository, IAuthenticationService authenticationService) { this.MemberRepository = memberRepository; this.AuthenticationService = authenticationService; }
Once we put the above method in the Member class, our domain-object is ready for the dependency injection. The final Member class will look something like this:
public class Member { [Inject] public InjectDependencies(IMemberRepository memberRepository, IAuthenticationService authenticationService) { this.MemberRepository = memberRepository; this.AuthenticationService = authenticationService; } //The dependencies private IMemberRepository MemberRepository { get; set; } private IAuthenticationService AuthenticationService { get; set; } public long MemberId { get; set; } public string UserName { get; set; } public string Password { get; set; } public string Email { get; set; } public string FirstName { get; set; } public string LastName { get; set; } //A member must be able to sign in. public IDictionary<string, list<string>> SignIn(bool remember) { var errors = new Dictionary<string, list<string>>(); //Use of injected object var existingMember = MemberRepository.GetSingle(member => member.UserName == this.UserName && member.Password == this.Password); if (existingMember != null) { //Use of injected object AuthenticationService.SignIn(this.UserName, remember); } else { if (!errors.ContainsKey("UserName,Password")) { var errorMessages = new List<string>{WTDErrors.UsernameOrPassword}; errors.Add("UserName,Password", errorMessages); } } return errors; } //end SignIn() //A visitor must be able to register to become a member public IDictionary<string, list<string>> RegisterToBecomeMember() { //even this could be injected, but I'm ok with this for now. var validator = new MemberValidator(MemberRepository); var errors = new Dictionary<string, list<string>>(); //The validator objects will contain all the validation rules, so that the domain model doesn't get cluttered. But still the domain object enforces the business rules. var validationResult = validator.Validate(this); if (validationResult.IsValid) { MemberRepository.Add(this); MemberRepository.Save(); } else { foreach (ValidationFailure failure in validationResult.Errors) { var errorMsg = failure.ErrorMessage; if (!errors.ContainsKey(failure.PropertyName)) { errors.Add(failure.PropertyName, new List<string>{errorMsg}); } else { errors[failure.PropertyName].Add(errorMsg); } } } return errors; } //end RegisterToBecomeMember() }
Now, let's move forward and make our DbContext ready to inject the dependencies.
public class NInjectDataContext : DbContext { public NInjectDataContext(DbConnection dbconnection, IKernel kernel): base(dbconnection) { this.Kernel = kernel; (this as IObjectContextAdapter).ObjectContext.ObjectStateManager.ObjectStateManagerChanged += ObjectStateManagerChanged; } //end constructor public DbSet<member> Members { get; set; } private void ObjectStateManagerChanged(object sender, CollectionChangeEventArgs e) { if (e.Action != CollectionChangeAction.Add) return; var state = (this as IObjectContextAdapter).ObjectContext.ObjectStateManager.GetObjectStateEntry(e.Element).State; //discard all entities that are not loaded from database. if (state != System.Data.EntityState.Unchanged) return; ObjectContext_ObjectMaterialized(e.Element); } //end ObjectStateManagerChanged() private void ObjectContext_ObjectMaterialized(object element) { if (Kernel != null) { //This is the place where injection takes place. Kernel.Inject(element); } } //end ObjectContext_ObjectMaterialized() public IKernel Kernel { get; private set; } }
This is it, now we have prepared a model that is dependency ready, and a DbContext that can inject dependencies after the objects are materialized. As of now following code will return a member with the dependencies injected:
var kernel = new StandardKernel(); var context = new NInjectDataContext(new SqlConnection(ConnectionStringProvider.ProductionConnection), kernel); var queriedMember = context.Members.Where(member => member.Id ==1).SingleOrDefault();
Now, I just have a single concern that our Domain-model and the DbContext has yet another dependency upon, the NInject framework. But NInject is a very fantastic and power-full framework which has many extension points, so turning off the dependencies is quite a breeze.
This post has already become very long, so we will try to look at how the dependencies can be removed from NInject in some later posts. Any thoughts are very welcome.
References:
The code for DbContext, has been taken from (with some modifications).
http://rogeralsing.com/2009/05/30/entity-framework-4-entity-dependency-injection/
I was motivated to write this code, and in turn this blog, after reading this stack-overflow question:
http://stackoverflow.com/questions/4562276/entity-framework-ctp5-and-ninject-as-my-ioc
N.B.
I'm not a native English speaker, so I'd like to apologize if the above contents aren't very readable. Also, since this is my first blogging experience I'd be very thankful to anyone who points me towards the right direction.