Nido Framework
It is free and it is an open source project. So let us read through these interview questions to understand Nido.
What is ‘Nido’?
Nido is a code framework, a common project, an architectural pattern, written on Microsoft .NET/C# 4.5, to help software engineers to develop their systems faster. This framework is extracted from a common library we maintained in our development center to improve our work. We wanted to do three main things with ‘Nido’.
-
Speed – We want you to write your code faster and faster but without ignoring the quality as well as budgetary requirements.
-
Freedom – We want to let you go, when you want to go. When you are on leave or enjoying your week we don’t want to call claiming that there is an emergency. We should be able to handle it with who ever present in the work place at that time.
-
Advancement – We help you establish a methodical approach to improve your development center over time.
Nido is not a one time static framework, it will continue to evolve and befits you. Keep in touch with the Nido Framework @ CodePlex.
Note: Nido framework is best architect-ed for small to medium applications development and currently, we are using it to develop a fairly large "ERP" system that has nearly 2000 tables. So as per our experience, the framework is stable enough.
Prerequisites to use 'Nido' Framework
Developer
- At least 3 - 5 years of development experience
- Understanding of "OOP" concepts, understanding "generic" concept is a must
- Entity Framework
- Code-First technique with existing database
System
- .Net Framework 4.0, or later
- Visual Studio 2010, or later
- Obviously some windows OS
Don’t you think we already have some framework?, so why you came up with a new one?
Yes, we do see many and also few good framework for .NET developers too. However ‘Nido’ framework is meant to fit into a niche that any of the other framework do not fit in to.
So let me explain this.. As I said, most of the software systems developed today are small to medium size systems. Given their sizes and the cost, no one actually want to hire an architect to do a design for those. To back that decision up, since these systems look simpler, software engineers themselves also feel comfortable handling the complexity alone. However when you analyze their lifecycle, you will understand that those software are also associated with significant level of complexities. But you will not see them up front or at the begining part of the lifecycle. As you go on the software expands. These could be minor changes that comes in isolated form, so that you don’t feel them as problems. You go ahead and patch them around the main core. However every time you do a change, they introduce complexities that eat little more processor time than they deserve. This goes on to make unstable, difficult to manage software modules.
Secondly, these minor changes are done by multiple people, they do them their way. So then the code become inconsistent, unstable and complex over time. This is the segment which is about 80% of our software falls into.
‘Nido’ suppose to address those issues, and is a complete solution given to this larger group of developers who work on those small to medium size systems. With ‘Nido’ you will start your system with minimum fuss and run through its life cycle smoothly and also very very fast.
Now.., tell me why do you always stress on fastness, does this also mean that.. other constrains.. Such as quality and budget of a software solution is not that important?
That’s a good question.. When I say ‘develop systems faster’ that fastness actually includes other constrains such as quality as well as budget. We have done that with the help of Nido's unique architecture… so I am going to explain those later.
It kind of make sense, today, businesses use IT as a weapon, a weapon to fight their competition. So now, let me ask the question again, why these businesses want that weapon faster? Would you shed some light on that?
Let me cut the long story short, in today’s postmodern business era the survival of the business is the ‘continuous growth’. To grow continuously, you need to expand your business and also need to change the way you do things internally, you may acquire, and merge with other businesses, and may put effort to reduce waste/ risk to add more and more values to your customers. But these introduce many changes to your work behavior and that create ripple effect on respective software systems you use as well.. These changes realted to software systems needed to happen faster. That is why speed is more important when it comes to software delivery. However it does not mean that you can ignore other things, but I want to stress that speed is the key factor.
‘Nido’, is a framework right? In summary, How you explain that to me? I mean, what benefits does it has?
Let me start it this way, any system can be mainly broken into three layers starting from the UI layer down to business logic and data access layer. Now, you may ask me, what is a system? Basically a system carries answers.. to your business problems, right?.
So if you use ‘Nido’ to find answers to your business problems, we will equip you with many weapons. Once configured, we will get you a pre-coded Data Access Layer (DAL) that has options to access data in every possible way you can think of. Then it will also code you a reasonably good business logic layer. For those it will use a technology called ‘t4template’. Once you reach this stage you will have number of discrete business functions that you can use to solve any business problems. So as the next step, you got to use those pre-coded functions to connect in meaningful manner, via UI layer to provide the required business solutions.
Additionally, among those solutions, you will find some common types of problems, that you provide solutions in many different ways. Let’s say things like
- Handling of log-in exceptions, display user friendly messages, tracking errors.
- Tracking changes done to important data items which is also called audit trails
- Validating records and encrypting sensitive data to protect their privacy
- Controlling complexity by mean of handling complex problems in one standard way
- Set standards pattern for coding
So these things are common for every other system you do, but with 'Nido' framework we introduce a common, standard way to solve all these problems.
With that, can I say that ‘Nido’ framework is a set of standards? Is that a right comment??
The answer is a No and a Yes, no mean there are many things that are being developed by ‘Nido’ team. They are not just standards they are codes written in generic forms. So once you integrate ‘Nido’ with your project, you inherit bulk of those feature to your project. You write few lines of codes to derive bulk of the features developed in generic form.
Yes, mean, there are certain other development that you can do, by adhering to certain standard or by extending the features given, to enhance some of those default features. On that aspect yes we define standards to make sure that we all use 'Nido' the same way.
What benefits that has, and also tell me.. Why my company should use ‘Nido’?
‘Nido’.. will gives you a number of benefits. You should carry your experience and learning forward.. from one system to the next, but having no methodical, logical approach as such to do it, that process is less efficient, but with ‘Nido’ you will be able to improve your developers in a more methodical manner, so as time progress you will take lesser and lesser time for coding. Additionally, the consistency and uniformity is important too. Further to that, ‘Nido’ will reduce developer individual dependencies too. We all as developers create dependancies with the code module we write. This is bad for us as well as for the company. We should avoid that and 'Nido' will help you do that.
Then again with 'Nido' it makes your work more predictable too. This is possible mainly because you re-use number of common libraries across many systems and do the development in similar manner irrespective of the type of system you develop. You start using 'Nido' to experience this. This also link with software estimation, the effort estimation is one of the most erroneous area. This is why companies find it difficult to earn profit from fix bid projects. However with improved predictability, with 'Nido' you will be able to do effort estimation more accurately than before.
I mean, I am not telling that you will get these benefits only through ‘Nido’, any other well architected framework can give you these benefits. But for Microsoft .Net there aren't many such frameworks of this nature. So In that sense 'Nido' is a unique solution.
Design of the framework is very important, especially when we are to use it in every other system. So can you explain your design decisions and also the challenges you faced in coming up with a design for ‘Nido’?
Let me explain the big picture first. Think of an intelligent system that automatically changes and configures it based on the usage. As an example when a particular screen is used more often than others, the system intelligently changes the navigation path to allow access to those screen quicker, or when a particular field is continuously ignoring the system intelligently respond to it and redesign the UI to hide those that are not used. So that is where we are heading with ‘Nido’.
But obviously, that is the high-level goal. But on the real ground we are now working on the back end part of the code, there we let you auto create DAL and BLL with ‘Nido’. There we have made few design decisions.
Overview of the Nido framework, as you can see Nido will vastly reduce the size of your Business Logic and Data Access Layers.
-
Where to play? We tried to identify a play area for ‘Nido’. Most of the systems that developed today are small to medium size systems. Most of them are architecturally vulnerable too. So we decided to focus on those to give the correct architectural mix for them. So we will be playing with small to mid-size systems.
Further to it, with ‘Nido’, the focus is to help design the back end. That way will will help you to write the back-end code faster. Now, those spare time you earned, can be/ should be invested on the UI layer to make it creative and user friendly.
-
How to play? So the second design decision is to find a method to achieve those goals. As a prime rule, we didn’t want to make thing complex. We focused on simple designs. Therefore, we put extra efforts to make things simpler for us, we developers too. We know that we all as coders forget the coding standards as well as architectures we established initially after sometime. That is why we proposed to have a separate governing body to control and monitor the coding. This framework will be that controlling body. This is where we impose standards, best practises, coding patterns etc. You use 'Nido', while we play a role for you to improve the framework every year. If you think you also want to do it, then join us. We all, will improve while other regular developers, can enjoy the freedom.
In order to make things simpler for all of us, the ‘Nido’ team decided to develop many code in the form of generic classes so that you don’t have to do complex coding or remember anything. Then again the bulk of the code is generated for you automatically using t4tempaltes. Once you start using 'Nido' you will realize how easy it is to use ‘Nido’ framework. You will not see anything not useful in ‘Nido’, we are very careful as to what we add to ‘Nido’ framework.
We use some of the well-known third-party libraries such as
- EntityFramework
- EntityFramework.Extended
- EntityFramework.BulkInsert-ef
- RefactorThis.GraphDiff
- EntityFramework.MappingAPI
- CompareNETObjects
- Log4Net
If you want more precise details of some of the design decisions then you can refer to another article called 'Architecture Guide: ASP.NET MVC Framework + N-tier + Entity Framework and Many More' that I wrote sometime back. Even though that architecture is not a one to one map of the one that I have used here, you will be able to understand all major design decision by refering to that.
How can I configure ‘Nido’?
The easiest path is to install it through NuGet via Package Manager Console. Please follow the steps given below.
-
Open Visual Studio 2010 or 2012
-
Create a new ‘Class Library’ type Project
-
Name it <You Project Name>.Bll, it is important to have this ‘.Bll’ suffix as with ‘Nido’ framework, we will be creating a project that virtually combine the DAL with the BLL. So the project we are creating now is the whole back end system of your project.
-
Click \View\’Other Windows’\’Package Manager Console’ to open to ‘Package Manager Console’.
-
On the console type ‘Install-Package NidoFramework’. Click Enter. Now, wait for few minutes until you get ‘Nido’ framework and respective libraries being installed.
-
Important: You need to give permission to override the existing ‘App.config’ file. So you may check ‘Package Manager Console’, there it should prompt for permission.
-
Creating the database to test the project. If you already have a database, you may ignore this step..
-
You may find a SQL scripted database together with some sample data in it, inside the DB folder of this newly created project.
-
First Create a Database with the name ‘School’ (this is just for a test run) in your MS SQL database (preferably MSSQL 2008 of higher) and run the script found inside ‘Sample_Db_Bak.Sql’ on that database.
-
This will create a database with multiple tables with data.
-
There are three files (tt files) inside the ‘Templates’ folder. You may go to each tt file starting from the ‘Models.tt’, ‘Handler.tt’ and to ‘DbContext.tt’ and change the connection string in each of those file separately (Yes, I will make it a common variable). Look for a variable with the name “connectionString”. As you save the changes, it should automatically started to generate respective files. However if it didn’t, you may right click on each of them and select ‘Run Custom Tool’ to trigger it manually.
Note: Please make sure that your database is adhering to the basic guidelines given in the documentation section.
-
Use Models.tt to generate model classes. They map directly with your database tables. However you have the option to add additional fields to these classes by flagging them with [NotMapped] Attribute (you may see some sample properties in those auto generated models). Once the class are created copy them over to ‘Models’ folder.
-
Use Handler.tt to generate handler classes. They are used to interact with the database. You may copy the generated classes to the ‘Handlers’ folder. Please refer to documentation to understand the usage of them.
-
Use DbContext.tt to generate the DB class and then copy them to ‘DB’ folder. This is a representation of the database context class.
-
Create your front end solution (Web, Desktop, Web Service, Win Service etc.) and add project reference to the above BLL project to use ‘Nido’ framework.
-
For further details you may read the documentation and also may see the sample project. Additionally you may also look in to our usage guide videos.
How can I write my Code on ‘Nido’, can you please give me some basic tips?
Now once you cofigure 'Nido', you are ready with your backend, next you need to create a front end for the project. Add a new web application, desktop application or any other project to your solution. Add reference to the business logic layer (BLL) project you just created. Additionally you also need to add references to all other third-party dlls that are used in ‘Nido’. As the final step you may add the connection string to the web.config or app.config file as below. This is how 'Nido' knows where to find your database.
Improtant: The ‘Nido’ framework is tested with MS SQL Server 2008, but it should theoritically work with all MS SQL versions and any other database that Entity Framework 6.0 works with. In order to configure ‘Nido’ framework with the database you need to have the following entry in to your configuration file.
<connectionStrings>
<add name="name of the DBContext class"
connectionString="data source=<db server>;
initial catalog=<database>;user id=<user name>;password=<pass word>;
multipleactiveresultsets=True; timeout=500" providerName="System.Data.SqlClient" />
</connectionStrings>
Important Note: Here the "name of the DBContext class" is the name of the DB Context you find inside the DB folder of your BLL project. This is the very same configuration you do with entity framework code first technique.
Loading Data from the Database
If you want to load data from the 'Student' table then you got to use the ‘StundentHandler’ class (these are auto created for you). Let me show you how we can load data from the 'Student' table.
protected void LoadData()
{
StudentHandler handlerStudent = new StudentHandler();
GenericResponse<IEnumerable<Student>> response = handlerStudent.GetAllGeneric();
if (response.Successful)
{
this.GridView1.DataSource = response.Result.ToList();
this.GridView1.DataBind();
}
else
this.DisplayError(response.Messages[0]);
}
If you want to include multiple tables and load them together you may specify that in the ‘handlerStudent’ before calling to load the data.
handlerStudent
.Include("HomeAddress")
.GetAllGeneric();
This will load the 'Student' record together with the associated ‘HomeAddress’ of each student. This student handler class will supports loading student records in all possible ways. Let me show you a little more complex way. The code below will load Students with ‘HomeAddress’ as well as ‘StudentCourses’ and also with their ‘Courses’ (These features are extracted from EntityFramework 6.0). Additionally it will do a conditional load and only load the student with ‘IsActive’ field having ‘true’ value.
handlerStudent
.Include("StudentCourses.Course")
.Include("HomeAddress)
.GetAllGeneric(x => x.IsActive == true);
These loads design to have minimum database hits and roundtrips so you are advice to call method such as ‘ToList’ or ‘ToArray’ only at the last minute after filtering the record set you actually wanted. If you call them beforehand and try doing filtering after that, then you will ended up loading lots of unnecessary data to your machine memory.
Important: This return object of a call carries many details about the call, its status and error encountered. Additionally it has a user friendly message for you to display for the user when the method call encountered any errors. ‘Nido’ Log any errors in to an exception log file which you can configure via ‘web.config’ or ‘app.config’ file with a reference ID. Then it return you a message that need to display to the user with that reference ID. So that users need to report the error with the reference ID where developers can directly track the respective error with the ID in the exception log. Exception log configuration details can be obtain by referring to the log4Net project site. Anyway when you install 'Nido' through package manager console you will get a App.Config file which has the log4net setting to write errors in to a txt file. Set the thresold level to 'Info' to see a track of all the transactions.
<param name="Threshold" value="INFO"/>
For your understanding let me show you a sample infomation log (it keep track of regular error logs but this is when you set the thresold to 'INFO') below. Notice the amount of detail it captures. This type of logs are very important for initial production releases where you are not very sure about the stability of the system. This will help you trace initial production errors easier. However as the system get more and more stable you can increase the thresold level to reduce logs.
2014-01-02 09:45:37,530 [5] INFO DemoTest.Bll.Handlers.CourseViewHandler - Calling start for GetAllGeneric()
2014-01-02 09:45:37,545 [5] INFO DemoTest.Bll.Handlers.CourseViewHandler - Calling End Successfully for GetAllGeneric()
2014-01-02 09:45:38,103 [5] INFO DemoTest.Bll.Handlers.StudentHandler - Calling start for GetFirstGeneric(x => ((x.Age == 10) AndAlso (x.CanDelete == True)))
2014-01-02 09:45:38,263 [5] INFO DemoTest.Bll.Handlers.StudentHandler - Calling End with erros for GetFirstGeneric(x => ((x.Age == 10) AndAlso (x.CanDelete == True)))
We are right now using the 'info' logs to track performance issues. What we do is, we enable info logs immediately after a release goes on to production environment and then we keep on monitoring the logs. One learning we made is that it is better to use 'views' for complex retrievals. Then again highly optimized 'Bulk Insert' option is also introduced after reviewing our info logs. Let me take the opportunity to specially thank to EntityFramework.BulkInsert team and maxlego.
I heard that with 'Nido' You can Load Data from the Cache, is that true?
Yes, This is another important feature that I like to highlight. When you load data from the database it is constly. Therefore you may have thought as to why I need to hit the database over and over to load data. Yes with 'Nido' you can cache them. If you want to cache data, then you need to create a cache policy. Check the code below and we have provided this feature with the help of the 'EntityFramdwork.Extended' library developed by Paul Welter and his team from 'loresoft'.
StudentHandler handlerStudent = new StudentHandler();
var tasks = handlerStudent.GetAllFromCache(x => x.IsActive == true
, new NidoCachePolicy(300)
, tags: new[] { "ActStudents", "All sActive Students" });
NidoCacheManager.Current.Expire("ActStudents");
This feature can be used to load records that are not often updating. This way you keep data in memory so that you don't need to hit the database repeatedly. You can use the processor power and network bandwidth gained to do other vital data retrievals.
However there may also have situation where you need to force the framework to load data from the database. In such case you call the following code to expire the cache object.
NidoCacheManager.Current.Expire("ActStudents");
Update Record back to the Database
If you want to update student data back to the Student table then you got to use the ‘StundentHandler’ class. Let me show you how we can do that. This is a one simpler way of updating the records.
StudentHandler handlerStudent = new StudentHandler();
GenericResponse<Student> stdRes = handlerStudent
.GetFirstGeneric(x => x.StudentId < 34);
if (stdRes.Successful)
{
stdRes.Result.Age = 1000;
GenericResponse<Student> stdUpRes = handlerStudent
.UpdateGeneric(stdRes.Result);
}
However you may need to do much more complicated updates, as an example if you are updating multiple records you may need to attach those separately, in such cases you may want to use the attach method to attach related other objects. This feature developed using ‘EntityFramework’, so whatever you learning you gather by using EF can be used here.
handlerStudent.AttachChild<StudentCourse>(studentObj.studentCourseObj)
.AttachChild<Address>(studentObj.addressObj)
.UpdateGeneric(studentObj);
However you may do much more complicate update with more predictable and stable method and that will be to do it as follows.
private void UpdateRecord(Student student)
{
student.Age = 308;
student.Description = "Editted on " + DateTime.Now;
student.Name = string.Empty;
student.StudentCourses.FirstOrDefault().Course.Period = 308;
student.StudentCourses.FirstOrDefault().Course.Name = "Eddited on " + DateTime.Now;
student.StudentCourses.Remove(student.StudentCourses.FirstOrDefault(x=>x.StudentCourseId == 10));
Course course = new Course();
course.EndDate = DateTime.Now;
course.IsActive = false;
course.IsWeekEnd = true;
course.Name = "Newly added course on " + DateTime.Now;
course.Period = 10;
course.StartDate = DateTime.Now;
StudentCourse stdCourse = new StudentCourse();
stdCourse.StudentId = student.StudentId;
stdCourse.CourseId = course.CourseId;
stdCourse.Course = course;
student.StudentCourses.Add(stdCourse);
StudentHandler stdentHandler = new StudentHandler();
GenericResponse<Student> response = stdentHandler.UpdateGraphGeneric(student
, map => map.OwnedCollection(p => p.StudentCourses
, with => with.OwnedEntity(p => p.Course)));
}
This feature is developed with the help of a third party library called ‘GraphDiff’, which is being developed by Brent Mckendrick. If you want more details on this you may refer to his blog. You may search for this on the internet to find more. You will be amazed to see some of the nice features he has developed to support complex model updates via entity framework.
The update option given below is interesting. This will look for all the student with their studentId greater than ‘0’ and change their name to ‘Updated’. This is a efficient way to do bulk updates. This feature is made available by using ‘EntityFramework.Extended’ by LoreSoft. You may refer to their website to see all the nice features they have given so that you will use them in ‘Nido’ as well.
StudentHandler stdentHandler = new StudentHandler();
handlerStudent.UpdateGeneric(t => t.StudentId > 0
, t2 => new Student { Name = "Updated" });
Delete a record(s) from the Database
The delete function is fairly straight forward. You can use either of the following options to delete a record(s) from the database.
-
handlerStudent.DeleteGeneric(entityObject);
-
handlerStudent.DeleteGeneric(12); // By passing the primary key
-
handlerStudent.DeleteGeneric(x=>x.StudentId>10); // By passing a expression
Add record(s) to the Dayabase
handlerStudent.AddGeneric(entityObject);
or the one below. The below method is developed with the help of EntityFramework.BulkInsert, which was developed by maxlego and his team. You can check its perrformance and other benifits from the respective codeplex site.
handlerStudent.AddBulkGeneric(entityObjectList);
I heard that you have an option, where a developer can directly test a system on PRODUCTION with ‘Nido’, is that true?
Yes. This is one of those very useful feature. You know, sometime we developers come up with strange coding issues. Some of them occurs only in production environment, where you have to debug on production to recreate the issue. We have a solution for you, Nido allows you to test your system on production environment with production data but ends it without changing the production data. If it sounds important to you read on...
Say, it is a web application, what you need to do is, load the source project in visual studio and change the web configuration file to connect with the production database with the special configuration given below. Then you can debug the system with production data. It will show updates you do on your sessions (and it is only for you with that configuration file). This is very important and useful to trace those rare errors that you only find in production environments.
In order to get this working, you just have to add the following configuration to your configuration file.
<add key="EnableTesting" value="true"/>
I have some sensitive data, which I need to keep in my databasee in encrypted form. Do you have a solution to Encrypt Sensitive Data with ‘Nido’?
Yes, you can do that with Nido. You only need to flag the respective property of the model with the ‘Encrypted’ attribute. Once you do that the records will be auto encrypted when saving and will get decrypted when retrieving back from the database to display on the user interface (UI). So with this feature you can keep sensitive data in encrypted form in the database.
public class Student : BaseObject
{
[Encrypted]
public string Name { get; set; }
}
In certain cases, it is important keep track of changes done to records. This is important for ISO certification as well. Does ‘Nido’ has something for this?
Tracking changes or audit trail is an important feature. You may need to keep track of changes done to some important records. The history of changes needed to be tracked. In such cases you can configure ‘Nido’ to do it for you.
This is how you do it. In the Models folder of your BLL project, which the ‘Nido’ installation has created, there is a file called ‘AuditTrails.txt’, inside this file you will have guidelines to enable this feature. Follow that..
Once you do that your system is ready for audit tracking. Now you need to tell the framework the fields that you need to track. For that, you only have to mark the fields with ‘Auditable’ attribute as below.
public class Student : BaseObject
{
[Auditable]
public string Name { get; set; }
}
When you coding on a framework there are many recommendations to get the best out of it. So what other Recommendations you have for developers?
Yes, we have few other recommendations let me specify them in order..
Recommendation 1
Let's assume that you want to combine records from multiple tables. Then you can use not mapped fields.
As an example if you want to display the 'Student' along with student address, then you may add a string as a not mapped field and load the student including address as below.
StudentHandler stdentHandler = new StudentHandler();
stdentHandler.Include(student=>student.Address).GetAllGeneric();
Student Model need to following update
Public class Student
{
[NotMapped]
Public string StudentAddress { get { return Address.ToString(); } }
}
Recommendation 2
If you want do complex data retrievals the best opption is to use views and that will improve performance as well reduce network traffics. So to improve the function you may create a new view object and load all records in to the view. This way you can load the view in to a newly created model object to pass it on the UI.
In this sense you have to manually create a model that map with the fields that you have in the database view. Then you also need to create a new handler class same way you have done that for table objects. Then you can load the view just like you load any other database table. This is highly efficient way to do complex data retrievals.
Recommendation 3
Use SP to reduce network round trips. If you are calling a SP and does not expect a return then it is fairly clean. But if you expect a return object as well, then you got to create a new model object to tally with the records you get from the SP. Since it is a flat object you DON'T have to derive this model from a ‘BaseObject’ as usual. On the same node, define a one main seperete class to handle all SP call. Now you can do the SP call as below..
public GenericResponse<IEnumerable< Return Object >> CustomGetMethod()
{
try
{
myDbContext db = new myDbContext();
IEnumerable<Return Object> s = db.ExecuteStoredProcedure("<you sp name> @param1
, @param2"
, new SqlParameter("@param1", param1 value)
, new SqlParameter("@param2", param2 value);
return SelectSuccessResponse(s);
}
catch (Exception e)
{
return HandleException<IEnumerable<Address>>(e);
}
}
Recommendation 4
There are few Database guidelines that you need to adhere if you are to easily use Nido.
- Give meaningful names for tables
- Use a primary key for all the tables. The primary key should have the table name followed by the suffix 'Id' (e.g. primary key = TableNameId). This is applicable for composite tables as well.
- 'Name' column would come handy if you are to display table records in a drop-down box.
- Foreign key name of a table also may use table name followed by the suffix 'Id'
- They can be created just like you create them in EF.
- Use Stored Procedures as much as possible to avoid unwanted database round trips.
What other benefits it has in summary?
- Exception login with log4net
- Transaction login with operation details and parameters
- Audit trail - Log audit trail, compliant with ISO certification requirements
- Special testing mode - special testing mode to test the system in production environment with the support of a in memory version of the production database, that is you will be using the production database without actually changing the production data.
- Bulk Operations, bulk update, bulk delete facility via Entity Framework Extensions
- Cached linq query results
Additional References
History
- 2013-12-18: Initial version
- 2014-01-07: Added How to Cache
- 2014-10-01: Completely revamp the whole article in respond to some user comments