kgrzybek / sample-dotnet-core-cqrs-api

Sample .NET Core REST API CQRS implementation with raw SQL and DDD using Clean Architecture.
https://www.kamilgrzybek.com/design/simple-cqrs-implementation-with-raw-sql-and-ddd/
MIT License
2.88k stars 646 forks source link

why not just inject IDbConnection instead of ISqlConnectionFactory? #9

Closed amingo123 closed 4 years ago

amingo123 commented 4 years ago

Very great DDD sample.

I have one question confuse me. why not use IDbConnection directly but use ISqlConnectionFactory to wrap a connection? Any concern about use IDbConnection ?

https://github.com/kgrzybek/sample-dotnet-core-cqrs-api/blob/master/src/SampleProject.API/Customers/DomainServices/CustomerUniquenessChecker.cs#L9

Thank you.

kgrzybek commented 4 years ago

The main reason is to use the same connection during "request" handling. It is solved using IoC container:

builder.RegisterType<SqlConnectionFactory>()
    .As<ISqlConnectionFactory>()
    .WithParameter("connectionString", _databaseConnectionString)
    .InstancePerLifetimeScope();

Request means HTTP request or internal command processing.

amingo123 commented 4 years ago

The main reason is to use the same connection during "request" handling. It is solved using IoC container:

builder.RegisterType<SqlConnectionFactory>()
    .As<ISqlConnectionFactory>()
    .WithParameter("connectionString", _databaseConnectionString)
    .InstancePerLifetimeScope();

Request means HTTP request or internal command processing.

Thanks for your reply. I think the same connection determined by InstancePerLifetimeScope, the IDbConnection can be registered the same way. builder.RegisterType() .As() .InstancePerLifetimeScope();

kgrzybek commented 4 years ago

You mean this?

builder.RegisterType<SqlConnection>()
.As<IDbConnection>()
.WithParameter("connectionString", _databaseConnectionString)
.InstancePerLifetimeScope();

This has some issues:

  1. When the connection is opened?
  2. You need to explicitly close connection according to https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlconnection.open?view=netframework-4.8 :

If the SqlConnection goes out of scope, it is not closed. Therefore, you must explicitly close the connection by calling Close.

  1. When the connection is closed, should be reopened if necessary
  2. In factory you can configure other options like timeout etc.
amingo123 commented 4 years ago

You mean this?

builder.RegisterType<SqlConnection>()
.As<IDbConnection>()
.WithParameter("connectionString", _databaseConnectionString)
.InstancePerLifetimeScope();

This has some issues:

  1. When the connection is opened?
  2. You need to explicitly close connection according to https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlconnection.open?view=netframework-4.8 :

If the SqlConnection goes out of scope, it is not closed. Therefore, you must explicitly close the connection by calling Close.

  1. When the connection is closed, should be reopened if necessary
  2. In factory you can configure other options like timeout etc.

Thanks for your explanation!