Practical Implementation of in-memory Repository Patterns

Recently I have been given a task to demonstrate my key knowledge on OOP and Design Patterns and its practical implementation.

The Task

Create an in memory implementation of IRepository<T>

Hints:The solution should be developed in a Test Driven approach, we expect the code you write to have excellent unit test coverage.Keep the solution simple, we value simple architecture and SOLID principles, but we’re not looking for over engineered design.The code should be self-explanatory, documentation should not be required to understand the code.

I have create a solution for that but prior to that I would like to explain what is repository pattern and explain it in my own words and how I implemented by describing my thoughts.

Repository Pattern: what is it?

Repository pattern is a pattern for data access. This is a common design pattern inside of applications that need to perform data access.

Why do we use the Repository Pattern?

Because most of applications do need to access data from some Data source or perhaps multiple data sources, and for that we need to use data access code throughout Business Logic or Domain Model. It is true that data access code typically is very repetitive and it’s concerned with low-level infrastructure details such as opening SQL connection and managing parameters etc.

This pattern will help us to separate the data access code from business logic and increase the testability of an application without real data in the place. and we can simulate data access in unit tests and have a component that works with in-memory data instead of web service or against any database schema.This allows us to unit test to be very repeatable, very low friction and not much effort to set up and it has quick feedback cycle.

So Let us crack on.

A Repository is going to be a class that you build for your application and it’s going to exist somewhere between the Business Logic and the Data Source of your application. You might have multiple repositories inside of an application. You might have a repository for each type of entity that you need to store.

Here we have been given an opportunity to create a solution for in-memory Generic IRepository Implementation which allows us to Save, Delete, Retrieve all or Find data by Id. Because it is generic in nature it can be easily implemented for any other entities.  Likewise here we are talking very specific implementation for IStoreable which has a Property of IComparable. (You must have knowledge of how IComparable works and implements and further details can be found here


So let us get back to our original given problem statement:

Following interfaces has been given and we have to implement the concrete class for them.

The first file is IStoreable.cs as given below:

   1: using System;


   3: namespace RamInfosystems.Interview

   4: {

   5:     public interface IStoreable

   6:     {

   7:         IComparable Id { get; set; }

   8:     }


  10: }

Now next file is IRepository.cs as given below:

   1: using System;

   2: using System.Collections.Generic;


   4: namespace RamInfosystems.Interview

   5: {

   6:     // Please create an in memory implementation of IRepository<T> 


   8:     public interface IRepository<T> where T : IStoreable

   9:     {

  10:         IEnumerable<T> All();

  11:         void Delete(IComparable id);

  12:         void Save(T item);

  13:         T FindById(IComparable id);

  14:     }

  15: }


And we need to create some test in Unit Test file.

My approach to solve this is by applying Test first. Clearly here the implementation of an interface is generic type and has constraints of type Interface. And this will harness the element which we can compare and test against it. So far nothing unusual.

So when you implement the IRepository Class you also need to implement  IStoreable as well. Which I think first you need to figure it out what need to be achieved.

   1: public class TestStoreable : IStoreable

   2:     {

   3:         public string Name { get; set; }

   4:         public IComparable Id { get; set; }

   5:     }


So what we need to do here is Implement the IRepository interface and its 4 of Methods as such All, FindByID, Delete and Save. It was pretty obvious that implementation is a key for the each of operation required to be tested. I have to add a property call Name as string to attach.

I started with unit test and create my first test method named Test_Repository_List_Returns_IEnumberable_CorrectType as follows:

   1: [Test]

   2: public void Test_Repository_List_Returns_IEnumberable_CorrectType()

   3: {

   4:   repository = new Repository<TestStoreable>();

   5:   this.expected = repository.All();

   6:   Assert.IsInstanceOf<IEnumerable<TestStoreable>>(expected);

   7: }

Small explanation about the long name. I intend to do readable code as needed and what  my code does is reflect by its name for example test repository list returns when IEnumberable with correct type.

But I don’t have any implementation of Repository or any implementation of All(). Let’s implement it as below:

   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Text;


   6: namespace RamInfosystems.Interview

   7: {

   8:     public class Repository<T> : IRepository<T> where T : IStoreable

   9:     {

  10:         private List<T> entities;


  12:         public Repository()

  13:         {

  14:             entities = new List<T>();

  15:         }


  17:         public IEnumerable<T> All()

  18:         {

  19:             return entities;

  20:         }

  21:         ///Not fully implemented. 


  23:     }

  24: }

so when we call repository.All() it expected to be IEnumberable of generic type and List<T> is a same of the type.  Trick here is a concrete implementation of IStoreable gives us a opportunity to test all() method’s implementation.

Further on Delete(IComparable id) and Save(T item) implementation also based on the writing test first approach, Arrange, Act and Assert is cycle for TDD and I follow the same.

   1: [Test]

   2: public void Test_Repository_Save_AddNewItem()

   3: {

   4:    repository = new Repository<TestStoreable>();

   5:    newItemToBeSaved = new TestStoreable { Id = 1, Name = "ItemToBeSaved" };

   6:    repository.Save(newItemToBeSaved);

   7:    expected = repository.All();

   8:    Assert.IsTrue(((IEnumerable<TestStoreable>)expected).Contains(newItemToBeSaved));

   9: }


  11: [Test]

  12: public void Test_Repository_Delete_An_Existing_Item()

  13: {

  14:    repository = new Repository<TestStoreable>();

  15:    anExistingItem = new TestStoreable { Id = 1, Name = "AnExistingItemToBeDeleted" };


  17:    repository.Save(anExistingItem);

  18:    repository.Delete(1);

  19:    expected = repository.All();


  21:    Assert.IsFalse(((IEnumerable<TestStoreable>)expected).Contains(anExistingItem));

  22: }


Now it is obvious for method Delete we are providing an ID (which is IComparable) and which leads to additional method to create as it requires Predicate of its type and we can fetch through the Id by lambda expression  as follows

   1: private Predicate<T> MatchedId(IComparable id)

   2: {

   3:   return match => match.Id.Equals(id);

   4: }


Alright. so it help to find an Id which provided in the Delete method. Also it add an advantage to avoid a duplicate id in the Save operation shown as follows

   1: public void Save(T item)

   2: {

   3:    Delete(item.Id); // Avoid Duplicate

   4:    entities.Add(item);

   5: }


Here it might get tricky as Lazy evaluation of Find as we are passing IComparable Id which lead us to do certain things.  

   1: [Test]

   2: public void Test_Repository_Find_By_Id()

   3: {

   4:     repository = new Repository<TestStoreable>();

   5:     someItem = new TestStoreable { Id = 2, Name = "SomeItem" };

   6:     anExistingItem = new TestStoreable { Id = 1, Name = "ExistingItem" };

   7:     newItemToBeSaved = new TestStoreable { Id = 3, Name = "NewItemToBeSaved" };

   8:     repository.Save(someItem);

   9:     repository.Save(anExistingItem);

  10:     repository.Save(newItemToBeSaved);


  12:     expected = repository.FindById(2);


  14:     Assert.AreEqual(someItem, expected);

  15: }

And finally Implementation of FindById.

   1: public T FindById(IComparable id)

   2: {

   3:     return entities.Find(MatchedId(id));

   4: }


This will harness all the uses of Predicates and Generic list to find and match equal ids. This technique will help to enhance in-memory sorting and searching very quickly. However I haven’t included any stress-test to generate let us say 100 Million records and measure performance against the memory load or anything as it was out of scope for me at this stage. But Later I am thinking to write a separate article for it.  

I have tried to implement and develop this task using my ability to provide demonstration about how to implement the Repository Pattern for in-memory. 


There are a couple consequences to using the Repository Design Pattern. First, you should have an increased level of abstraction inside your application. This is good because it should mean that you’ll have less duplicated code. It also means that you should have code that’s more maintainable, more flexible, and more testable, however, you do have some additional interfaces, some additional classes, some people who are not familiar with the design pattern might need to look at this and figure out exactly what’s going on before they can catch on. When you have data access logic buried right inside of your business code, sometimes it’s very easy to look at that and understand what’s going on, but it just doesn’t scale up well, and in complex applications, you really need this increased level of abstraction just to manage the complexity. Another consequence of the Repository Design Pattern is that you are one step further away from the data. Since the Repository is shielding you from the underlying infrastructure, sometimes it can also be more difficult to get hints into that infrastructure that can help it optimize some of the operations that it needs to perform against the Data Source.


Here I tried to explain the Repository Design Pattern and how we can use it to keep Business Logic and Domain Model free of data access code and away from infrastructure code and actual components that talk to the database.

Using the Repository Pattern, I was able to write more maintainable code and easily unit test code. And  I showed a specific example that implemented a generic repository in C# code, the IRepository<T> interface. Using the magic of Generics, I was able to provide a single concrete implementation of this interface that covers most of our needs in an application.

If you are looking for a code or repository you can get it from code project and stack overflow as link given below:

Introduction First Video Post

Hi all, my name is Ravi Lodhiya and I am a Full stack developer, this is my first video post. I am looking for a Contract opportunity in the Microsoft Technologies stack. I am available immediately for an interview. Please email me your Job Specification. Thanks for watching. I hope to speak you soon. Bye.

Simple can be harder than complex

Simple Can be harder than complex

Simple can be harder than complex: You have to work hard to get your thinking clean to make it simple. But it’s worth it in the end because once you get there, you can move mountains.

-Steve Jobs

Motivation make my day.

Do you need a resource to complete IT project/s? Yes. Then call me now…

Every company needs resources. Resources to complete projects where budget has been already allocated.  Now problem is with very little unemployment in the UK, companies are struggling to get hold of good resources and workforces, people are moving getting better wages and of course Brexit on the horizon and it has started its negotiation process. Yet all of this uncertainty, projects need to be carried out and delivered constantly, Pressure is mounting to make financial targets on Project Managers and Teams.

In this tough time, few things happening to the existing projects either project needs to keep on hold or hire more resources, or delegating projects/workloads to offshore or inland third-party (if it is safe to do so.) and on the top budget is limited and time is burning quickly.

Hire Ravi Lodhiya as a contractor

With this in mind, and as an experienced IT Contractor (trying to be Freelancer) I have few things to offer in this crucial time:

  • I can come to rescue your projects or workload if you delegate me.
  • I can help you/your company to find resource for your troubled IT projects.
  • I can help you to motivate your team and engaging them to better perform.
  • I can be honest to assess your estimates for the project and add value to it.
  • I can bring your project on track and if your budget is tight then find alternative resources for that.
  • As an independent entity, I  can be more resourceful to your enterprise by more cost-effective and reliable, affordable and promising.  While you are searching with your current recruitment agency to fill the gap in your team, I can surely add value to your projects and keep balls rolling till you find right candidate as a permanent staff or may be help your trainees to come up to speed.

So if you have a project going on trouble due to  lack of resources or new greenfield project on the horizon but not able to prove by recruiters or want to get an idea about how much it is actually going to cost. Just email me your details via contact page here.

I usually turn around your projects quickly and we can build long-term relationship as it grow.

p.s.: I am not a recruiter or neither representing them. I am an independent contractor work as a limited company and try to rescue enterprises and deliver value to their projects by offering my ability.

So if you reading this and feel that it is better to contact me here for further discussion. Believe me you won’t be disappointed.

AngularJS 2 for .net Developer

AngularJS 2 for .net developer – Not only Course Completed but developed and deploy complete solution to azure.


Happy with the results. Just thinking to add to GitHub and Code Project with Learning articles.


How do I deliver small projects or tasks?

Recently I have been asked that how do I deliver small projects or tasks? What is my approach to solve a problem/task?

Well I said POC (Proof of Concept) because I think it is a one of cost effective way to tackle small projects and tasks, Also it helps to deliver 80 percent functionality or requirements asked by users. It also backs KISS (Keep it Simple Stupid!) rule. Most often stack holders are not so clear with their ideas or concepts, or not able to put a business cases against the benefits over ROI, which I think its fair on them, POC can rescue it. I see it as a tool that try before you buy in.   I consider this as maximum throughput of Return on Investment. Also it will give a chance to refine complex processes to more normal forms.

Right so let us understand what is POC?

Proof Of Concept

A Proof of concept (POC) is a realization of a certain method or idea to demonstrate its feasibility, whose purpose is to verify that some concept or theory has the potential of being used. A proof of concept is usually small and may or may not be complete.

A proof of concept in software aims to determine the solution to some technical problem or to demonstrate that a given configuration can achieve a certain throughput.


The Proof of Concept approach – A Time Travel to a successful Project


The Proof of Concept approach is practiced for various client requirements to provide the customer with the opportunity to “test drive” core processes in order to validate its needs are met as expected. The value proposition for a customer doesn’t end there-by investing a part of the total project cost up-front customers are able to identify and circumvent complex challenges that could become showstoppers later. In this way, a Proof of Concept would act as the first step of the blueprinting phase – very much like a conduit or bridge to a successful project launch. By leveraging the POC approach, we were able to rapidly prototype core business processes as requested by the customer.

The Proof of Concept approach Benefits

  • Clarity in need/problem formulation;
  • Number/quality of new ideas;
  • New knowledge;
  • Special planning;
  • New ways of thinking;
  • Level of planning;
  • Management of time;
  • Planning capabilities;
  • Efficiency of execution;
  • Strategy formulation;
  • Cost Effective;
  • Low in budget;
  • Low in risk;

Right so we understand the POC and its process but actually can you explain it with an example?

A Successful Client Consulting

Yes sure Let us say for an example, As an admin I want a dashboard which allows me to monitor who has login to the system and reports on their action lists such as assigned,  pending and completed tasks.

I have estimated the work involved in it was around 6 days and budget was around £1500.

So with a POC approach, I have created a web application which has functionality of above and simple report on action lists of the user and user management functions such as CRUD. Now with an exception of no need of prettiness on look and feel wise  but signed off on a condition if approved then they will allocate more fund on further development.

After It was demonstrated successfully and stack holders has given further requirements to enhanced functionality and user experience.  

The technologies I have used was MVC, ASP.NET and SignalR (which gives me real time update on who is logged in).  

Consultant engagements beyond simply purchasing expertise require the development of a relationship between the consultant and the client.

Consultants add value by addressing both content and process issues based on expertise, methodology and general problems solving skills.

My Journey–From Developer To Entrepreneur–Day 8 of 100

Day eight, Friday 14th August 2015

Notes from Yesterday:

So started bit laid back but later on  I was able to recover my productive thoughts and ideas, I started bit late and hassle gone through stress,but other than the working part I was so motivated later in the day. When you try to something and if it is constantly on your mind, your mind start to observe and creates a way to make it happen, I could see it, visualize it, feel it, through my heart and mind.


Plan for today:

Friday 14th August 2015

Time Hours Plan Action Result
6:30 am
9:00 am
1 hr
3 hrs.
Get rituals done, arrange plan day Get all duck line up
Late wake up
Awake bit late but I am sure I will recover it.
7:30 am
4 hrs.
3.5 hrs.
Development Plan
Spend time with Forex Bot Generation

Write some algorithms to help machine learning

Not so innovative but yet something to work with.

11:30 am 1 hr. Lunch Break
12:30 pm 3.5 hrs. Project Planning and proposal for next week job.
4:30 pm 2.0 hrs. No plans yet Had Nap and refresh Rest for a bit.
6:30 pm 4.5 hrs meeting Friends for drinks and dinner    
11:00 pm 1 hr. Quick catch up if I have strength.    
Now I am just putting this to rest. Yet lot to come and it will come soon as well. So hold your breath.

My Journey–From Developer To Entrepreneur–Day 7 of 100

Day 7, Thursday 13th August 2015

Notes from Yesterday:

Yesterday was really good until, I realize that foolish thing at Squash Booking – I thought I have booked 7:20 in the evening, but actually it was 17:20 (24 hours) format. What a suck. Anyway. Get out quickly from that stick to my plan and later clean my desk  Here is the photo attached.

Office Clean

Plan for today:

Today I am going to start with training and later on catch up with all different cancellation and refunds for all sort of things, Later I will start Sprint planning and start executing it. And if weather is good I will take Krisha to the near by Park.

Time Hours Plan Action Result
6:30 am 3 hrs. Daily Routine, Get Ready, Meditate, Training from Get into action today bit late but started with true energy Awesome morning rituals.
9:30 am 2 hrs. Sort out World pay, Proxy IP and other direct debits, Call and Write EE for Refund as well as New Sim Card. Yep Done, New Sim not possible with desired old numbers Happy with Plan, Cool stuff.
11:30 am 4.5 hrs. Development as define in Sprint planning I suppose to work on sprint but not yet. Disappointment and not able to see why I was not able to.
5:00 pm 2.5 hrs. Take Krisha to Park/ Swimming Change in plans Took Krisha to Leicester Lays for swim. Good time. On the way back I flicked some ideas while driving
5:00 pm 2 hrs. Summarized work  
7:00 pm
7:30 pm
2 hrs. Dinner and chill out Yes  that I definitely deserved I was still in my mind set to play with my Ideas
9:00 pm 1.5 hrs.
3.5 hrs
Plan next day and week
Write a prototype Program which can generate Tick Data for Gold (XAUUSD) with randomness which can be use in  
back testing of any of my stretegies.
Ideas buzzing my mind and I have just plan how to crunch big simulation for Forex Tick Data for anything. Awesome, I feel proud of myself, although it was bit late but I did what I wanted to do. Rock On.

So Now I am going to write my forex robot which will generate bucks BIG bucks for me, and may be who ever want to be associated with me. I am writing for next day Plan. But At the moment I am wide awake and hyper for doing something crazy. Just wait and watch.

Custom Software Development Checklist

Custom database software development is facilitated by the use of a checklist of standard questions to be answered before a system is created, and before analysis begins. This checklist is provided to assist in the Analysis/Requirements phase of a new custom software development project.


If you are interested in having 21st Century Technologies, Inc. create a new system for you, then the following checklist and the associated answers will facilitate the analysis process. The answers can be e-mailed or faxed to us at the email address and fax number at the bottom of the page.




1. Desired delivery date or proposed project schedule.

2. Business reason for, and urgency of project.

3. What are the cost constraints?

4. Use cases – description of how each group of users will be using the system.


a.    General business process – web user will buy a product, web user will add a customer, web user will add contact information, etc.

b.    Input/Output – web users will enter data into forms, data will be imported, administrator must run many management reports, administrator needs to export to Excel and text, etc.

c.    Frequency of activity – many times each day, once daily, weekly, etc.

d.    Cycles of activity – weekly sales reports to all sales managers on Monday morning, close books at end of year, etc.




1.    Do you have a desired development tool or technology in mind? You may want to split the application into some parts that can be run on a Windows workstation computer, while other parts (like reports, or timecard entry screens) are accessed via a web browser on your local intranet. Web applications and reports can be viewed on all computer types and operating systems that are capable of viewing web pages. Some tools currently available to build the system are listed here:


·         C#/VB.NET

·         ASP.NET

·         Active Server Pages or Cold Fusion for robust database driven Web applications

·         ColdFusion

·         Visual Basic

·         SQL Server

·         MS Access

·         JavaScript – for cross browser compatibility,

·         VBScript – for server scripting, and client scripting if Internet Explorer is

the only client browser

·         Dreamweaver – for higher ended client functionality

·         SQL Server Reporting Services

·         Crystal Reports – for Windows and Web based reports

·         ActiveReports

·         Excel

·         PowerPoint

·         Interactive Voice Response (IVR) Systems – dial 1 for English, 2 for



2.If other applications are involved (MS Word, MS Excel, QuickBooks, etc.), what version will be used?

3. Desired screen resolution (800×600, 1024×768, etc.),

4. Screen Size (15", 17", 19”, 21")

5. Preferred Font and size (Arial 10, Times New Roman 12, etc.)?

6. Target Windows version for each client computer in the system (98, NT 4.0, 2000, XP, 2003 Server, etc.),

7. Web Server – MS Internet Information Services (IIS), Apache, etc.

8. Target computer Operating System if not a Windows Platform – Apple, Unix, Linux, etc.

9. Target workstation hardware for all client stations,

a. Clock speed –1333, 1500, 2000, 3000, etc. MHz,
b. Hard drive space – 100, 200, 400, etc. Gbytes,
c. RAM – 128Mb, 256Mb, 512Mb, 1Gb, etc.

10. If a network application, which network and version? –Windows, Novell 3.1, Novell, etc.

11. What are the drive letters for the networked back end databases if a network application? F, G, H, etc.? This reduces the deployment effort by developing in the same environment as the target workstations.

12. If available and pertinent, please provide a network configuration diagram with paths to server (where database will reside) and all clients, security/user groups, etc.

13. Is 24×7 (24 hours a day, 7 days a week) uptime required? If so, please explain the business need. We will discuss this further. The cost goes up as more uptime is required. More resources are needed – various personnel on pagers, redundant computers or components like power supplies RAID or mirrored hard drives, etc.

14. Is Internet/Intranet data access desired?

a. For data entry?
b. For report reviewing only?
c. To disseminate existing documents?
d. To email notification of pre-determined business trigger events (project milestone met and approved, employee appraisal ready for approval, etc.)?

15. Is Security desired?

a. Extremely high network (Internet) security – firewall, proxy server, etc.
b. Database level security – MS Access has security, but SQL Server has a much tighter security model tied in with the Win 2000/NT operating system.
c. Application level security
d. Minimum (pseudo) security algorithm – low cost
e. Please specify User Groups that may have special Security needs requiring different levels of security:

i. Administrative Assistants
ii. Analysts
iii. Engineers
iv. Managers
v. Company Owners
vi. System Administrators

16. Are Backup Scenarios currently in place? Backups will be an integral component of the system. The importance of this cannot be over emphasized.

a. Daily, Weekly, Monthly onto tape
b. Daily, Weekly, Monthly onto CD or other optical drive
c. Onto another computer
d. Regular backups located at a remote site

17. Are Anti-Virus protection and policies in place? It is an important part of ensuring that a system stays up and running.

18. Will remote troubleshooting be desired? The addition of Error Processing and Logging software will facilitate remote support and troubleshooting.

19. Desired Documentation?

a. None
b. Installation
c. User
d. Administrator
e. Software
f. On-line help
g. Special
h. All of the above

20. What is the proficiency level of all users for the target tools and environments – Windows, Excel, etc.?

21. Will interfaces to other systems (accounting, payroll, another database, GIS, truck routing, etc.) be required? This will affect the data model and system configuration, so early planning for these interfaces is critical to their successful inclusion into the system.

22. Is an audit trail function desired for changes to existing data? What parts of the system will need to be audited?

23. Is government reporting or data security required – Sarbanes Oxley, HIPAA, etc.

24. Number of reports. A sample hardcopy or at least hand drawing of each will significantly help in determination of report prices and commonalties (company headers, formats, etc.). Important items are:

a. Number of sections including sort groups,
b. Definition of the source data for all fields in each section and their calculation method,
c. Summaries,
d. Desired output format:

i. Windows screen preview
ii. HTML
iii. E-Mail
iv. PDF
v. Delimited Text
vi. Excel spreadsheet
vii. Other outputs

25. Is an ad hoc user-defined reporting, data retrieval, or analysis (On Line Analytical Processing (OLAP), Data Mining, etc.) capability desired?

26. Is an installation program needed for distribution of an application to many users?

27. Is an automated network or internet installation desired?

28. Are custom point to point communications needed? This may also include automated faxing.

29. Special Considerations:

a. Unique business rules, calculations, desired warnings, etc.
b. Significant text parsing
c. Known or possible issues and problems that may be alleviated with testing
d. Voice driven capability
e. Multiple databases (Access and SQL Server, Oracle, etc.)




1. How many users are expected on the system in the near (first 6 months) and long (1 – 3 years and past) term?

2. How many users are expected to use the system at the same time during peak periods in the near and long term?

3. What type of data traffic will be on the network for the near and long term – numbers, text, images, video, multi-media, etc.?

4. What is the expected volume of traffic for the near and long term?

5. What is the estimated number of data records to be stored for the near and long term?

6. Do we need to import data from existing files or systems? Note that Characters like ‘ " # have special significance in data processing and conversion, and require special code handling. Names (D’Joy) and other data fields may contain these characters.

a. No. Example data will usually be provided in database, text, or spreadsheet format. This helps significantly in system testing and allows for error discovery and error trapping before the system is delivered.

b. Yes.

i. Is all or part of the existing data needed? What parts?
ii. Can use of the existing data be stopped while we convert the data into the new system?
iii. Is this a one time data conversion, or will we have to import data from existing systems regularly?
iv. Are some fields mostly blank?
v. Are some desired fields missing?


Proof Of Concept License Module –Developed, Tested and Delivered

Proof of concept - License Module

License Module Developed {full SDLC, TDD }. And Those who are looking for perfect solution for software, or if you have a concept to develop and want to make license your self. here is the solution. Email me for your custom requirements. {lodhiya[at]gmail[dot]com}

Windows Live Tags: Proof,Concept,License,Module,SDLC,solution,self,Email,custom,requirements

WordPress Tags: Proof,Concept,License,Module,SDLC,solution,self,Email,custom,requirements