SkillAgentSearch skills...

Smooth.IoC.Dapper.Repository.UnitOfWork

Smoother IoC using Dapper Dapper.FastCRUD with Repository and UnitOfWork patterns

Install / Use

/learn @generik0/Smooth.IoC.Dapper.Repository.UnitOfWork
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Project Icon Smooth.IoC.Dapper.Repository.UnitOfWork

generik0 VSTS Build Status NuGet

This package it created to "FIX" the contradictory concepts behind the Repository and UnitOfWork patterns together with using inversition of control / dependancy injection.
Also i wanted to make the creation of sessions (IDbConnection) and UnitOFWork's (a Transaction) by the injected factory automatically connection / begin transaction on creation, and disconnect/commit on disposal. Hence making database work become nice and smooth like....
I also want to be able to do unit (integration) testing with e.g. a Sqlite but the production database engine could be e.g. a MsSQl. This is possible now...

So far there are examples of Autofact, Castle.Windsor, Ninject, Simpleinjector, StructureMap, and Unity.

WARNING: Until Smooth.IoC.Dapper.Repository.UnitOfWork reaches version 1.0, I reserve the right to make minor backwards-incompatible changes to the API.

Table of Contents generated with DocToc

What are the features of the library?

The library gives you the building blocks to:

  • Create Sessions from the IDbFactory in your methods, IDbFactory should be injected into your class's. As Session extends IDbConnection and will Open on the factory spawning the session and dispose the connection on disposal of the connection.
  • Your Sessions can create UnitOfWork's. As Session extends IDbConnection and will Open on the factory spawning the session and dispose the connection on disposal of the connection.
  • If your logic just needs "just a" UnitOfWork with a session that has the same scope, the factory can create it for you.
  • The IRepository and abstract concrete class should be used on your individual repository classes to provide simple and basic calls. But ofcasue you can add all the queries you want into your Repositories and use the dapper and dapper.FastCRUD (or any other extensions) functionality provided to you.
  • The repository abstract classes use Dapper.FastCRUD to give you a fluent ORM experience with the most common calls.
  • This library does not lock you to using dapper and FastCRUD, you can use any library you like that extends IDbConnection and IDbTransation, and still use the IDbFactory, ISession and IUnitOrWork.
  • Implemented for .net 4.5.2, .net 4.6.1+, .net 1.6 standard+.

You will have to register the IDbFactory and IUnitOfWork manually, along with your other registrations. But below in this readme and in the test examples i have added examples for: Autofac, Castle.Windsor, StructureMap, Ninject, Unity. I did not want to add al sorts of IoC containers to the package, so please look at the examples. And If you have better knowledge of an IoC framework, please let me know if it can be done better, and smoother...

About Dapper and Dapper.FastCRUD

I use Dapper and Dapper.FastCRUD for my sql work. It is made by the very cool StackExchange mob.
Dapper is a micro ORM data does only what you ask of it through queries. Dapper
There is an extension to Dapper called Dapper.FastCRUD. This adds fluentness to dapper also for complex joins etc. Dapper.FastCRUD.

Dapper is not Entity, Linq2Sql nor NHibernate. It is a micro ORM and really really fast. Dapper.FastCRUD does not add the FULL fluent ORM experience. So you will need to think about what you do.
But you are also in control of the code and optimization of calls. For me, i believe that the "big" ORMs do to much, and Dapper together with Dapper.FastCRUD is the perfect amount of just doing enough...

The drawback with Dapper.FastCRUD is it may fail if you don't give it the wrong SqlDialect. So i have extended FastDappers IDbConnection extensions so the projects own ISession and IUnitOfWork are extended. Then the FastCRUD IDbConnection extension method extended by ISession or IUnitOfWork extensions in the package. This insures that the dialogue is set correct, if needed. This means that your Entity can only be used for one database type per ioc container / executing assembily. So you can also use a different databae for your tests than your production code.

  • This will only effect FastCRUD calls using ISession or IUnitOrWork instances. Not IDbConnection instances.
  • If you want your entity to span across more than one database, you can use the RepositoryBase to extend from bypassing the Repository abstraction.
  • I have created a SqlDialectInstance (Singleton) expert that can help you set the dialogue. Please use it if you have issues with your session and sql dialect.
  • I have created a SqlHelper, that insures FastCRUD's SqlDialect is set if you decide you need a FastCRUD "Sql" helper method. Please use my SqlHelper otherwise your SqlDialect might be frozen. It is available for Repositories as "Sql" a proctected property.
  • TA dialogue helper is also available in your repository through "SetDialogueOnce" method. You will need to use it for joins.. (Hint: if your dialogue gets stuck in the wrong state you can "reset" the FastCRUD mapping using OrmConfiguration.RegisterEntity<YouEnity>();)

You can do a lot fluently with FastCRUD. Check out there wiki:

Or as i have already menioned use dapper or any other extension utilizing IDbConnection and IDbTransaction...

What does this libray do?

All of the repository and UoW pattern examples i could find online did not include the usage of a factory for registration and injection. The session would typically be added to the constructor meaning when the session was disposed by one method, another method in the class could not use it any more. The examples with IoC used some very complex registration and multithreading code. But there really isn't a need for this!
Basically something didn't seam to fix with the typical UoW and Repository patterns together with IoC.
I also found that injecting a simple factory that could create simple IDbConnections and IDbTransactions was not good enough. Because more intelegence/help was needed. Hence the IDbFactory, ISession, IUnitOfWork, IRepository interfaces and logic was born...
At the same time it is very important that it be possible to use one connection for production code and another for unit testing (e.g. MsSql for production and Sqlite for testing).

  • Please note, that SqlLite only accepts IsolationLevel.Serializable for the uow. You will need to override the default IsolationLevel.RepeatableRead. This design allows for this. As your custom session interface is used as the generic for the repository, not the session class allowing for different connection strings. You can even use the same database migrations if you have done code first. I have used SimpleMigrations as it allows both console running for the production code / installer and inproc for unit testing.

You are welcome to look at the unit tests for examples or look below in this readme.

What this the package include?

So what i have done/created is this:

  1. IDbFactory is a simple interface that you register with your IoC. It can create/spwan ISession's and IUntOfWork's. But primary used in code to spawn Sessions or UnitofWork's with an attached session.
  2. ISession<TDatabase> (and Session<TDatabase> abstraction): Extends IDbConnection. You use it to extend your Database connection / Session type. Yours session classes and interfaces require a connection string. So If you have multiple database connections, you need 1 ISession and Session extended Interface and class per database. When the session is created by the factory it connects to the database, when it disposes it discontects and disposes. For Castle Windsor it also untracks the object. You can use the session for any IDbConnection or dapper (or extension) framework you like, as ISession extends IDbConnection ;-). The ISession also has a Dapper.FastCRUD extension so the SqlDialect is automatically set for the enitity depending on the connection.
  3. IUnitOfWork (and UnitOfWork): Extends IDbTransaction. You don't need to extend anything with this. When you have created a session in you code, you can create a uow from the session. Then the session is created by the factory it begins a transaction (isolation i a pa

Related Skills

View on GitHub
GitHub Stars71
CategoryDevelopment
Updated1y ago
Forks26

Languages

C#

Security Score

80/100

Audited on Dec 10, 2024

No findings