Dapper with .NET Core - injected SqlConnection lifetime/scope - c#

I'm using .NET Core Dependency Injection to instantiate a SqlConnection object during the application startup, which I'm then planning to inject in my repository. This SqlConnection will be used by Dapper to read/write data from the database within my repository implementation. I am going to use async calls with Dapper.
The question is: should I inject the SqlConnection as transient or as a singleton? Considering the fact that I want to use async my thought would be to use transient unless Dapper implements some isolation containers internally and my singleton's scope will still be wrapped within whatever the scope Dapper uses internally.
Are there any recommendations/best practices regarding the lifetime of the SqlConnection object when working with Dapper? Are there any caveats I might be missing?
Thanks in advance.

If you provide SQL connection as singleton you won't be able to serve multiple requests at the same time unless you enable MARS, which also has it's limitations. Best practice is to use transient SQL connection and ensure it is properly disposed.
In my applications I pass custom IDbConnectionFactory to repositories which is used to create connection inside using statement. In this case repository itself can be singleton to reduce allocations on heap.

Great question, and already two great answers. I was puzzled by this at first, and came up with the following solution to solve the problem, which encapsulates the repositories in a manager. The manager itself is responsible for extracting the connection string and injecting it into the repositories.
I've found this approach to make testing the repositories individually, say in a mock console app, much simpler, and I've have much luck following this pattern on several larger-scale project. Though I am admittedly not an expert at testing, dependency injection, or well anything really!
The main question I'm left asking myself, is whether the DbService should be a singleton or not. My rationale was that, there wasn't much point constantly creating and destroying the various repositories encapsulated in DbService and since they are all stateless I didn't see much problem in allowing them to "live". Though this could be entirely invalid logic.
EDIT: Should you want a ready made solution check out my Dapper repository implementation on GitHub
The repository manager is structured as follows:
/*
* Db Service
*/
public interface IDbService
{
ISomeRepo SomeRepo { get; }
}
public class DbService : IDbService
{
readonly string connStr;
ISomeRepo someRepo;
public DbService(string connStr)
{
this.connStr = connStr;
}
public ISomeRepo SomeRepo
{
get
{
if (someRepo == null)
{
someRepo = new SomeRepo(this.connStr);
}
return someRepo;
}
}
}
A sample repository would be structured as follows:
/*
* Mock Repo
*/
public interface ISomeRepo
{
IEnumerable<SomeModel> List();
}
public class SomeRepo : ISomeRepo
{
readonly string connStr;
public SomeRepo(string connStr)
{
this.connStr = connStr;
}
public IEnumerable<SomeModel> List()
{
//work to return list of SomeModel
}
}
Wiring it all up:
/*
* Startup.cs
*/
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
//...rest of services
services.AddSingleton<IDbService, DbService>();
//...rest of services
}
And finally, using it:
public SomeController : Controller
{
IDbService dbService;
public SomeController(IDbService dbService)
{
this.dbService = dbService;
}
public IActionResult Index()
{
return View(dbService.SomeRepo.List());
}
}

I agree with #Andrii Litvinov, both answer and comment.
In this case I would go with approach of data-source specific connection factory.
With same approach, I am mentioning different way - UnitOfWork.
Refer DalSession and UnitOfWork from this answer. This handles connection.
Refer BaseDal from this answer. This is my implementation of Repository (actually BaseRepository).
UnitOfWork is injected as transient.
Multiple data sources could be handled by creating separate DalSession for each data source.
UnitOfWork is injected in BaseDal.
Are there any recommendations/best practices regarding the lifetime of the SqlConnection object when working with Dapper?
One thing most of developers agree is that, connection should be as short lived as possible. I see two approaches here:
Connection per action.
This of-course will be shortest life span of connection. You enclose connection in using block for each action. This is good approach as long as you do not want to group the actions. Even when you want to group the actions, you can use transaction in most of the cases.
Problem is when you want to group actions across multiple classes/methods. You cannot use using block here. Solution is UnitOfWork as below.
Connection per Unit Of Work.
Define your unit of work. This will be different per application. In web application, "connection per request" is widely used approach.
This makes more sense because generally there are (most of the time) group of actions we want to perform as a whole. This is explained in two links I provided above.
Another advantage of this approach is that, application (that uses DAL) gets more control on how connection should be used. And in my understanding, application knows better than DAL how connection should be used.

Related

Decoupling EF6 from its custom Api

I would like to ask some help regarding Dependency Injection and, I think, architectural approach.
So, I have an ORM layer implemented by EF6 where the objects are described and Ef does what its business, etc. I created a custom library over it, called DatabaseApi and it is mentioned in the title as "Api", where I query the data and map it to datacontract objects. I do it for pure testing purposes. I would like to have the different libraries in my application testable.
I started to implement the code where I inject the DbContext but I don't know how to deal with the usings in this case.
I went through a few blogposts and articles about mocking and EF, especially this one but it is rather about testing EF itself and not about how to decouple it from other libraries. On the other hand, I assume my search keywords were not proper.
Do you know any good and usable tutorials and articles about how to decouple entity framework from other libraries?
Thanks in advance!
Examples:
I created an empty interface in order to the DbContext can be injectable. It is implemented by the databaseContext.
public interface IDatabase
{
}
public class DatabaseModelContext : DbContext, IDatabase{
public DbSet<TableOne> TableOne { get; set; }
public DbSet<TableTwo> TableTwo { get; set; }
}
In the custom Api library constructor I put together a code to resolve the interface by Unity. I don't know whether it is working or not. I haven't executed yet.
public partial class DatabaseApi : IDatabaseApi {
private readonly IDatabase iDatabase;
private readonly UnityContainer unityContainer;
public DatabaseApi()
{
this.unityContainer = new UnityContainer();
this.unityContainer.RegisterType<IDatabase, DatabaseModelContext>();
this.iDiLibDatabase = this.unityContainer.Resolve<IDiLibDatabase>();
}
}
And here is the problem. Due to the injection I'll have and interface but there are the usings which are important to manage the resource as far as I know. How to do it?
public partial class DatabaseApi : IDatabaseApi
{
public List<SomeDataContract> GetMainStructure()
{
var result = new List<SomeDataContract>();
//this is the old implementation
using (var database = new DatabaseModelContext())
{
//some data manipulation magic... :)
}
return result;
}
If you're okay using linq to objects as a core element of your domain access layer then exposing an IQueryable for access to the entities would work...
public interface IRepository<TEntity>
{
IQueryable<TEntity> AllEntities { get; }
}
With that, you can do your Where, Select, etc. without hard wiring directly to EF. Behind the scenes the IRepository implementations would deal with the EF portions, database connectivity, etc. There's no avoiding coupling the to EF at the data access layer. But you can keep it constrained to just that layer using something like you've started. Just make sure the database contexts used by your IRepository objects are the only objects working with EF.
Put another way: Don't have your IDatabase return entities. Just have it deal with the connections, and you should create another layer for domain object access which takes in an IDatabase. In the example I gave, somehow the IRepository implementations would take in an instance of IDatabase.
So, the solution is using Autofac DI framework. I found interesting questions and answers and two really helpful tutorials. Links below:
How do you reconcile IDisposable and IoC?
Dependency Injection with Autofac
Generic Repository and Unit of Work Pattern, Entity Framework, Unit Testing, Autofac IoC Container and ASP.NET MVC
Autofac homepage

How do I add a service layer to my UnitOfWork using Ninject?

I hit a little road block trying to set up DI.
So given that I have this controller:
public UsersController(IUnitOfWork unitOfWork)
{
// Stuff
}
I previously had this UnitOfWork implementation that accessed my repositories directly.
public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly DbContext _context = new DbContext();
public IRepository<User> Users { get { return new UserRepository(_context); } }
}
Ninject UnitOfWork code: Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
Now this actually works fine. However I want to change it so that instead of UnitOfWork containing the repositories, it contains services which take in multiple repositories.
public class UserService : IUserService
{
private readonly IUserRepository _userRepository;
public UserService(IUserRepository userRepository, /* Other repositories */)
{
_userRepository = userRepository;
}
}
Right now the only solution I can come up with is
public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly DbContext _context = new DbContext();
public IUserService UserService
{
get
{
return new UserService(new UserRepository(_context), /* etc. */);
}
}
}
This doesn't seem right. Now I'm creating all of the service dependencies myself.
I've seen posts on StackOverflow mentioning that it's better to have services access the multiple repositories and handle the business logic rather than having the controller (MVC application) worry about it.
Can't find any specifics on how to actually do this properly though. So how could I use Ninject to do what I'm after?
Sorry, this is really an overgrown comment but hey...
A DbContext is a Unit Of Work, and creating a monster unit of work that straddles two DbContexts is definitely not a general pattern (hence your question sez you)
The comments on this answer here to a related question stray into the same territory.
Questions to ask yourself before you try to solve it this way:
What are you attempting to accomplish with this Unit of Work of mine beyond having a DbContext?
Does this need to be transactional?
Is there actually a missing service in the middle which should have its own data that references the two other ones?
Does this need to straddle two Bounded Contexts? What if you need to pull them part again later?
If I had 3 cases of this in my app would I keep merging them into one BC? 4?
For me the crux is that creating your own UoW to wrap a UoW:
doesn't buy you much
makes it harder to reason about your core problem
If you are still going to shoehorn this stuff in with Ninject in the way, the technical approach is to use the Context Preservation and Factory Extensions together - go read the examples in their wikis. If you decide to strip things back, they probably still have parts to play too.
UPDATE: I catch your drift now - it's important to link to stuff like that which is guiding your thinking up front. First, go read this. Next, decide if you're going to have a Unit of Work. If so, who and where is going to Commit and Dispose it?
If the Repositories and/or Services are going to share either a UoW or a DBContext and something is going to centrally Commit stuff, then you bind the things to be Shared/Disposed InRequestScope to have it a) get a single shared instance b) get Disposal
My main concern remains whether all these abstractions are all actually benefiting things - are you really writing tests that use the abstractions (and not just for the first few)? Are you really going to switch repositories. I personally would go read the DDD book a few times as a better time investment.
I realise a lot of this is highly patronising and this is just a simplified question representing part of a larger problem, but I've just seen too many questions recently prompted by the intersection of wrapping layers and DI container trickery hence my rant. Rant complete, thanks!

Decoupled architecture

I'm working on a system where I'd like to have my layers decoupled as much as possible, you know, some kind of modular application to be able to switch databases and stuff without a serious modification of the rest of the system.
So, I've been watching for x-the time one of the talks of Robert C. Martin about good practices, clean code, decoupling architecture etc, to get some inspiration. What I find kinda weird is his description of the system Fitnesse and the way they've implemented store/load methods for WikiPages. I'm linking the video as well: Robert C. Martin - Clean Architecture and Design
What's he describing (at least from my understanding) is that the entity is aware of the mechanism how to store and load itself from some persistent layer. When he wanted to store WikiPages in-memory, he simply overrode the WikiPage and created a new InMemoryWikiPage. When he wanted to store them in a database, he did the same thing...
So, one of my questions is - what is this approach called? I've been learning the whole time about Repository patterns and stuff, and why should be classes like this persistence-ignorant, but I can't seem to find any materials on this thing he did. Because my application will consist of modules, I think this may help to solve my problems without a need for creating some centralized store for my entities... Every module would simply take care of itself including persistence of its entities.
I think the code would look like is something like this:
public class Person : IEntity
{
public int ID { get;set; }
public string Name { get;set; }
public void Save()
{
..
}
public void Update()
{
}
public void Delete()
{
}
...
}
Seems a bit weird, but... Or maybe I misunderstood what he said in the video?
My second question would be, if you don't agree with this approach, what would be the path you'd take in such modular application?
Please provide an example if possible with some explanation.
I'll answer your second question. I think you will be interested as well in Dependency Injection.
I'm not an expert on DI but I'll try to explain as clear as I'm able to.
First off, from wikipedia:
Dependency injection is a software design pattern that allows removing hard-coded dependencies and making it possible to change them, whether at run-time or compile-time.
The primary purpose of the dependency injection pattern is to allow selection among multiple implementations of a given dependency interface at runtime, or via configuration files, instead of at compile time.
There are many libraries around that help you implement this design pattern: AutoFac, SimpleInjector, Ninject, Spring .NET, and many others.
In theory, this is what your code would look like (AutoFac example)
var containerBuilder = new ContainerBuilder();
//This is your container builder. It will be used to register interfaces
// with concrete implementations
Then, you register concrete implementations for interface types:
containerBuilder.RegisterType<MockDatabase>().As<IDatabase>().InstancePerDependency();
containerBuilder.RegisterType<Person>().As<IPerson>().InstancePerDependency();
In this case, InstancePerDependency means that whenever you try to resolve IPerson, you'll get a new instance. It could be for example SingleInstance, so whenever you tried to resolve IPerson, you would get the same shared instance.
Then you build your container, and use it:
var container = containerBuilder.Build();
IPerson myPerson = container.Resolve<IPerson>(); //This will retrieve the object based on whatever implementation you registered for IPerson
myPerson.Id = 1;
myPerson.Save(); //Save your changes
The model I used in this example:
interface IEntity
{
int Id { get; set; }
string TableName { get; }
//etc
}
interface IPerson: IEntity
{
void Save();
}
interface IDatabase
{
void Save(IEntity entity);
}
class SQLDatabase : IDatabase
{
public void Save(IEntity entity)
{
//Your sql execution (very simplified)
//yada yada INSERT INTO entity.TableName VALUES (entity.Id)
//If you use EntityFramework it will be even easier
}
}
class MockDatabase : IDatabase
{
public void Save(IEntity entity)
{
return;
}
}
class Person : IPerson
{
IDatabase _database;
public Person(IDatabase database)
{
this._database = database;
}
public void Save()
{
_database.Save(this);
}
public int Id
{
get;
set;
}
public string TableName
{
get { return "Person"; }
}
}
Don't worry, AutoFac will automatically resolve any Person Dependencies, such as IDatabase.
This way, in case you wanted to switch your database, you could simply do this:
containerBuilder.RegisterType<SqlDatabase>().As<IDatabase>().InstancePerDependency();
I wrote an over simplified (not suitable for use) code which serves just as a kickstart, google "Dependency Injection" for further information. I hope this helps. Good luck.
The pattern you posted is an Active Record.
The difference between Repository and Active Record Pattern is that in Active Record pattern, data query and persistence, and the domain object are in one class, where as in Repository, the data persistence and query are decoupled from the domain object itself.
Another pattern that you may want to look into is the Query Object which, unlike respository pattern where its number of methods will increase in every possible query (filter, sorting, grouping, etc) the query object can use fluent interface to be expressive [1] or dedicated in which one you may pass parameter [2]
Lastly, you may look at Command Query Responsibility Segregation architecture for ideas. I personally loosely followed it, just picked up ideas that can help me.
Hope this helps.
Update base on comment
One variation of Repository pattern is this
UserRepository
{
IEnumerable<User> GetAllUsers()
IEnumerable<User> GetAllByStatus(Status status)
User GetUserById(int id)
...
}
This one does not scale since the repository get's updated for additional query that way be requested
Another variation is to pass query object as parameter to the data query
UserRepository
{
IEnumerable<User> GetAll(QueryObject)
User GetUserById(int id)
...
}
var query = new UserQueryObject(status: Status.Single)
var singleUsers = userRepo.GetAll(query)
Some in .Net world, Linq expression is passed instead of QueryObject
var singleUsers = userRepo.GetAll(user => user.Status == Status.Single)
Another variation is to do dedicate Repository for retrieval on one entity by its unique identifier and save it, while query object is used to submit data retrieval, just like in CQRS.
Update 2
I suggest you get familiar with the SOLID principles. These principles are very helpful in guiding you creating a loosely coupled, high cohesive architecture.
Los Techies compilation on SOLID pricples contains good introductory articles regarding SOLID priciples.

SOA, TDD, DI & DDD - a shell game?

Okay, I'm going to try and go short and straight to the point. I am trying to develop a loosely-coupled, multi-tier service application that is testable and supports dependency injection. Here's what I have:
At the service layer, I have a StartSession method that accepts some key data required to, well, start the session. My service class is a facade and delegates to an instance of the ISessionManager interface that is injected into the service class constructor.
I am using the Repository pattern in the data access layer. So I have an ISessionRepository that my domain objects will work with and that I implement using the data access technology du jour. ISessionRepository has methods for GetById, Add and Update.
Since my service class is just a facade, I think it is safe to say that my ISessionManager implementation is the actual service class in my architecture. This class coordinates the operations with my Session domain/business object. And here's where the shell game and problem comes in.
In my SessionManager class (the concrete ISessionManager), here's how I have StartSession implemented:
public ISession StartSession(object sessionStartInfo)
{
var session = Session.GetSession(sessionStartInfo);
if (session == null)
session = Session.NewSession(sessionStartInfo);
return session;
}
I have three problems with this code:
First, obviously I could move this logic into a StartSession method in my Session class but I think that would defeat the purpose of the SessionManager class which then simply becomes a second facade (or is it still considered a coordinator?). Alas, the shell game.
Second, SessionManager has a tightly-coupled dependance upon the Session class. I considered creating an ISessionFactory/SessionFactory that could be injected into SessionManager but then I'd have the same tight-coupling inside the factory. But, maybe that's okay?
Finally, it seems to me that true DI and factory methods don't mix. After all, we want to avoid "new"ing an instance of an object and let the container return the instance to us. And true DI says that we should not reference the container directly. So, how then do I get the concrete ISessionRepository class injected into my Session domain object? Do I have it injected into the factory class then manually pass it into Session when constructing a new instance (using "new")?
Keep in mind that this is also only one operation and I also need to perform other tasks such as saving a session, listing sessions based on various criteria plus work with other domain objects in my solution. Plus, the Session object also encapsulates business logic for authorization, validation, etc. so (I think) it needs to be there.
The key to what I am looking to accomplish is not only functional but testable. I am using DI to break dependencies so we can easily implement unit tests using mocks as well as give us the ability to make changes to the concrete implementations without requiring changes in multiple areas.
Can you help me wrap my head around the best practices for such a design and how I can best achieve my goals for a solid SOA, DDD and TDD solution?
UPDATE
I was asked to provide some additional code, so as succinctly as possible:
[ServiceContract()]
public class SessionService : ISessionService
{
public SessionService(ISessionManager manager) { Manager = manager; }
public ISessionManager Manager { get; private set; }
[OperationContract()]
public SessionContract StartSession(SessionCriteriaContract criteria)
{
var session = Manager.StartSession(Mapper.Map<SessionCriteria>(criteria));
return Mapper.Map<SessionContract>(session);
}
}
public class SessionManager : ISessionManager
{
public SessionManager() { }
public ISession StartSession(SessionCriteria criteria)
{
var session = Session.GetSession(criteria);
if (session == null)
session = Session.NewSession(criteria);
return session;
}
}
public class Session : ISession
{
public Session(ISessionRepository repository, IValidator<ISession> validator)
{
Repository = repository;
Validator = validator;
}
// ISession Properties
public static ISession GetSession(SessionCriteria criteria)
{
return Repository.FindOne(criteria);
}
public static ISession NewSession(SessionCriteria criteria)
{
var session = ????;
// Set properties based on criteria object
return session;
}
public Boolean Save()
{
if (!Validator.IsValid(this))
return false;
return Repository.Save(this);
}
}
And, obviously, there is an ISessionRepository interface and concrete XyzSessionRepository class that I don't think needs to be shown.
2nd UPDATE
I added the IValidator dependency to the Session domain object to illustrate that there are other components in use.
The posted code clarifies a lot. It looks to me like the session class holds state (with behavior), and the service and manager classes strictly perform actions/behavior.
You might look at removing the Repository dependency from the Session and adding it to the SessionManager. So instead of the Session calling Repository.Save(this), your Manager class would have a Save(ISession session) method that would then call Repository.Save(session). This would mean that the session itself would not need to be managed by the container, and it would be perfectly reasonable to create it via "new Session()" (or using a factory that does the same). I think the fact that the Get- and New- methods on the Session are static is a clue/smell that they may not belong on that class (does this code compile? Seems like you are using an instance property within a static method).
Finally, it seems to me that true DI
and factory methods don't mix. After
all, we want to avoid "new"ing an
instance of an object and let the
container return the instance to us.
And true DI says that we should not
reference the container directly. So,
how then do I get the concrete
ISessionRepository class injected into
my Session domain object? Do I have it
injected into the factory class then
manually pass it into Session when
constructing a new instance (using
"new")?
This question gets asked a LOT when it comes to managing classes that mix state and service via an IOC container. As soon as you use an abstract factory that uses "new", you lose the benefits of a DI framework from that class downward in the object graph. You can get away from this by completely separating state and service, and having only your classes that provide service/behavior managed by the container. This leads to passing all data through method calls (aka functional programming). Some containers (Windsor for one) also provide a solution to this very problem (in Windsor it's called the Factory Facility).
Edit: wanted to add that functional programming also leads to what Fowler would call "anemic domain models". This is generally considered a bad thing in DDD, so you might have to weigh that against the advice I posted above.
Just some comments...
After all, we want to avoid "new"ing an instance of an object and let the container return the instance to us.
this ain't true for 100%. You want to avoid "new"ing only across so called seams which basically are lines between layers. if You try to abstract persistence with repositories - that's a seam, if You try to decouple domain model from UI (classic one - system.web reference), there's a seam. if You are in same layer, then decoupling one implementation from another sometimes makes little sense and just adds additional complexity (useless abstraction, ioc container configuration etc.). another (obvious) reason You want to abstract something is when You already right now need polymorphism.
And true DI says that we should not reference the container directly.
this is true. but another concept You might be missing is so called composition root (it's good for things to have a name :). this concept resolves confusion with "when to use service locator". idea is simple - You should compose Your dependency graph as fast as possible. there should be 1 place only where You actually reference ioc container.
E.g. in asp.net mvc application, common point for composition is ControllerFactory.
Do I have it injected into the factory class then manually pass it into Session when constructing a new instance
As I see so far, factories are generally good for 2 things:
1.To create complex objects (Builder pattern helps significantly)
2.Resolving violations of open closed and single responsibility principles
public void PurchaseProduct(Product product){
if(product.HasSomething) order.Apply(new FirstDiscountPolicy());
if(product.HasSomethingElse) order.Apply(new SecondDiscountPolicy());
}
becomes as:
public void PurchaseProduct(Product product){
order.Apply(DiscountPolicyFactory.Create(product));
}
In that way Your class that holds PurchaseProduct won't be needed to be modified if new discount policy appears in sight and PurchaseProduct would become responsible for purchasing product only instead of knowing what discount to apply.
P.s. if You are interested in DI, You should read "Dependency injection in .NET" by Mark Seemann.
I thought I'd post the approach I ended up following while giving due credit above.
After reading some additional articles on DDD, I finally came across the observation that our domain objects should not be responsible for their creation or persistence as well as the notion that it is okay to "new" an instance of a domain object from within the Domain Layer (as Arnis eluded).
So, I retained my SessionManager class but renamed it SessionService so it would be clearer that it is a Domain Service (not to be confused with the SessionService in the facade layer). It is now implemented like:
public class SessionService : ISessionService
{
public SessionService(ISessionFactory factory, ISessionRepository repository)
{
Factory = factory;
Repository = repository;
}
public ISessionFactory Factory { get; private set; }
public ISessionRepository Repository { get; private set; }
public ISession StartSession(SessionCriteria criteria)
{
var session = Repository.GetSession(criteria);
if (session == null)
session = Factory.CreateSession(criteria);
else if (!session.CanResume)
thrown new InvalidOperationException("Cannot resume the session.");
return session;
}
}
The Session class is now more of a true domain object only concerned with the state and logic required when working with the Session, such as the CanResume property shown above and validation logic.
The SessionFactory class is responsible for creating new instances and allows me to still inject the ISessionValidator instance provided by the container without directly referencing the container itself:
public class SessionFactory : ISessionFactory
{
public SessionFactory(ISessionValidator validator)
{
Validator = validator;
}
public ISessionValidator Validator { get; private set; }
public Session CreateSession(SessionCriteria criteria)
{
var session = new Session(Validator);
// Map properties
return session;
}
}
Unless someone can point out a flaw in my approach, I'm pretty comfortable that this is consistent with DDD and gives me full support for unit testing, etc. - everything I was after.

Where to keep things like connectionstrings in an IoC pattern?

In my everlasting quest to suck less I'm currently checking out mvc Turbine to do the IoC dirty work.
I'm using the mvc Turbine nerd dinner example as a lead and things look rather logical thus far.
Although I'm refering to the turbine project here, I'm guessing the philosophy behind it is something general to the pattern
Safe for some reading and the rare podcast, I am new to the IoC concept and I have a few questions.
So far I have a IServiceRegistration entry for each IRepository I want to register
For example:
public class UserRepositoryRegistration : IServiceRegistration
{
public void Register(IServiceLocator locator)
{
locator.Register<IUserRepository, UserRepository>();
}
}
The concrete implementation of the IUserRepository needs some configuration though. Something like a connection string or in this case a path to the db4o file to use.
Where and to who should I supply this information?
Both Robert and Lucas hit the nail on the head with their answers. All the "extra stuff" for the account would live within the UserRepository class. This is currently the way the Turbine ND is implemented.
However, nothing stops you from creating a new class called ConnectionStringProvider that can then be 'injected' in your UserRepository which will provide the connection string (whether it be hard coded or read from a config file.
The code can be as follows:
public class ConnectionStringProvider {
public string ConnectionString {
get{
// your impl here
}
}
}
public class UserRepository {
public UserRepository(ConnectionStringProvider provider){
// set internal field here to use later
// with db connection
}
}
From here, you add a registration for ConnectionStringProvider within UserRepositoryRegistration class and Turbine will handle the rest for you.
In general, this is solely the concern of the concrete UserRepository that requires the connection string or database path. You would do just fine by dropping the path in the application configuration file and having your concrete repository pull out the configuration data directly.
Not all repositories are going to require this information, which is one of the reasons you have the abstraction in the first place. For example, a fast in memory concrete IUserRepository will not require a path to the database or likely any additional configuration to work.
Similar to Robert, I would recommend putting this into the application configuration file, however, with specific entries for each injection type. That way your connection string or path can be customized with each injection.

Categories

Resources