Will Entity Framework dispose the SqlConnection used in the GetFooFromUnmappableEntity method?
I have the following service:
public class FooService {
private readonly FooContext fooContext;
public FooService(FooContext fooContext) {
this.fooContext = fooContext;
}
public Foo GetFooFromUnmappableEntity(int id) {
return fooContext.Database.SqlQuery<Foo>(string.Format("select * from GetFoo({0})", id);
}
}
I'm using Ninject to manage my dependencies in a class library. So A binding exists somewhere like this:
Bind<FooContext>.ToSelf();
Ninject is an implementation of "dependency inversion", which means your dependencies are interfaces and Ninject will give you the implementations. You will want to create a IFooRepository that in its implementation uses FooContext. then IFooRepository gets injected into the constructor of IFooService and IFooService doesn't need to know anything about how the repository is implemented.
As far as disposing the SqlConnection, you will want to bind your repository .InRequestScope() and use the OnePerRequestModule which will dispose your objects at the end of the request.
Related
I have a use case in which I want to create repository instances using .NET Core dependency injection, but need to change one of the constructor parameters at runtime. To be precise, the parameter that should be decided at runtime is the "database connection", which will point to one or another database decided by the caller. This type, by the way, is not registered with the DI container, but all the others are.
The caller will use a repository factory type to create the repository with the desired connection.
It looks something like this:
class ARepository : IARepository
{
public ARepository(IService1 svc1, IService2 svc2, IConnection connection) { }
public IEnumerable<Data> GetData() { }
}
class RepositoryFactory : IRepositoryFactory
{
public RepositoryFactory(IServiceProvider serviceProvider) =>
_serviceProvider = serviceProvider;
public IConnection CreateAlwaysFresh<TRepository>() =>
this.Create<TRepository>(new FreshButExpensiveConnection());
public IConnection CreatePossiblyStale<TRepository>() =>
return this.Create<TRepository>(new PossiblyStaleButCheapConnection());
private IConnection Create<TRepository>(IConnection conn)
{
// Fails because TRepository will be an interface, not the actual type
// that I want to create (see code of AService below)
return ActivatorUtilities.CreateInstance<TRepository>(_serviceProvider,conn);
// Fails because IConnection is not registered, which is normal
// because I want to use the instance held in parameter conn
return _serviceProvider.GetService<TRepository>();
}
}
The following types were registered:
services.AddTransient<IARepository, ARepository>(); // Probably not needed
services.AddTransient<IService1, Service1>();
services.AddTransient<IService2, Service2>();
services.AddTransient<IRepositoryFactory, RepositoryFactory>();
And the factory would be used as such:
class AService
{
public AService(IRepositoryFactory factory)
{
_factory = factory;
}
public void ExecuteCriticalAction()
{
var repo = _factory.CreateAlwaysFresh<IARepository>();
// Gets the freshest data because repo was created using
// AlwaysFresh connection
var data = repo.GetData();
// Do something critical with data
}
public void ExecuteRegularAction()
{
var repo = _factory.CreatePossiblyStale<IARepository>();
// May get slightly stale data because repo was created using
// PossiblyStale connection
var data = repo.GetData();
// Do something which won't suffer is data is slightly stale
}
}
One of the reasons why I've kept all the code based on interfaces is, of course, for unit testing. However, as you can see from the pseudo-implementation of RepositoryFactory.Create<TRepository>, this is also a problem because I reach a point where I need to either :
determine the concret type associated to IARepository in the DI container to pass it to ActivatorUtilities in order to create an instance of it using the desired value of IConnection while resolving other constructor parameters with IServiceProvider, or
somehow tell IServiceProvider to use a particular instance of IConnection when getting a particular service
Is this at all possible using .NET Core DI?
(Bonus question: Should I have used another, simpler, approach?)
Update: I edited the sample code a little to hopefully make my intentions more clear. The idea is to allow the same repository, exact same code, to use different connections (which are configured during app startup) depending on the caller's specific needs. To summarise:
a Repository's responsibility is to execute the correct queries on a Connection when an action is requested.
the Caller will act on the data returned by the repository
however, the Caller might require the Repository to execute its queries on a particular Connection (which, in this example, controls data freshness)
Several workarounds have come up to the problem of injecting the right connection in the factory:
add a mutable Connection property to the Repositories and set it right after creation => what bothers me most with this solution is that it makes it very easy to forget to set a connection, for example in test code. It also leaves a door open to change a property of the repository which should be immutable.
do not inject the Connection in the class, but pass it as a method parameter instead => this makes for a less elegant API, since every method will now have an "extra" parameter, which could've been simply provided to the class to begin with, and the extra parameter is but an "implementation detail"
Since the IConnection will not be created by the DI, you could remove it from the repository constructor and have it as a property, then on your factory you can assign its value after the creation:
interface IARepository
{
IConnection Connection { set; }
}
class ARepository : IARepository
{
public IConnection Connection { private get; set; }
public ARepository(IService1 svc1, IService2 svc2)
{ /* ... */ }
}
class RepositoryFactory : IRepositoryFactory
{
/* ... */
private IConnection Create<TRepository>(IConnection conn)
where TRepository : IARepository
{
var svc = _serviceProvider.GetService<TRepository>();
svc.Connection = conn;
return svc;
}
}
The issue is in registering and attempting to inject IRepository at all. By your own spec, the repo cannot be created via dependency injection because the connection passed into it will vary at runtime. As such, you should create a factory (which you've already done) and register and inject that instead. Then, you pass in the connection to your Create method.
public TRepository Create<TRepository>(IConnection conn)
where TRepository : IRepository, new()
{
return new TRepository(conn);
}
You'll likely want to do some sort of instance locator pattern here instead. For example, you might store the created instance in a ConcurrentDictionary keyed by the connection. Then, you'd return from the dictionary instead. It's probably not a huge deal if the repository actually gets instantiated multiple times in race conditions - should just be a fairly minor object allocation. However, you can employ SemaphoreSlim to create locks when accessing the ConcurrentDictionary, to prevent this.
You haven't given a ton of info about your specific use case, so I'll also add a potential alternate solution. For this to work, the connection has to be defined by config or something. If it truly is runtime-provided, this won't work, though. You can provide an action to the service registration, for example:
services.AddScoped<IRepository, ARepository>(p => {
// create your connection here
// `p` is an instance of `IServiceProvider`, so you can do service lookups
return new ARepository(conn);
});
Its easy enough using NInject to establish dependency injection using interfaces.
So for example say I have a class like
public class WindowManagerService : IWindowManager
{
public WindowManagerService(ILogger logger) { }
}
It's easy to do something like this:
public class NinjectModuleLoader : NinjectModule
{
public override void Load()
{
this.Bind<IWindowManager>().To<WindowManagerService>().InSingletonScope();
}
}
and successfully configure the dependency injection.
However the problem I run into is when I need to provide a concrete instance of a class into the constructor such as the following example:
public class ObservableLogger : ILogger
{
public ObservableLogger(Dispatcher dispatcher) { }
}
In the above example I require the ability to pass in a concrete implementation of the dispatcher as I cannot use DI to establish this link and must reference the application wide Dispatcher instance.
Essentially what I wish to be able to do is something like this:
this.Bind<ILogger>().To(new ObservableLogger(Dispatcher)).InSingletonScope();
So how does one provide concrete implementations of dependencies to the NInject dependency manager?
You could use a factory method:
this.Bind<ILogger>().ToMethod(context => new ObservableLogger(Dispatcher));
...or create your own custom provider as explained in the docs: https://github.com/ninject/Ninject/wiki/Providers,-Factory-Methods-and-the-Activation-Context
There is also the ToConstant and ToConstructor methods:
this.Bind<ILogger>().ToConstant(new ObservableLogger(Dispatcher));
Please refer to this blog post for more information.
I have an issue where I want to use StructureMap to create singletons, but instead StructureMap creates multiple instances. I get confused when trying to read through the documentation on StructureMap on how to handle generics properly.
I have to instantiate a repository for a given entity while providing an instance for the data connection that needs the type of the entity due to generics.
Here is my code for VendorRepository, and many other repositories are structured in the exact same way. IVendorRepository needs IRepository injected with the Vendor type. And I'm not quite sure how to accomplish that in a singleton way.
public interface IVendorRepository {
...
}
public class VendorRepository : IVendorRepository {
private readonly IRepository<Vendor> _repository;
public VendorRepository(IRepository<Vendor> repository)
{
_repository = repository;
}
...
}
public class Vendor : DomainEntity
{
...
}
public class DomainEntity : IDomainEntity
{
...
}
Here is the the data connection portion. SqlRepository handles the actual connection via the currentSession. As far as I can tell, each DomainEntity repository (such as VendorRepository) would need it's own instance of the SqlRepository.
public class SqlRepository<T> : IRepository<T> where T : class, IDomainEntity
{
private readonly ISession _currentSession;
public SqlRepository(ISession currentSession)
{
_currentSession = currentSession;
}
...
}
public interface IRepository<T> where T : IDomainEntity
{
...
}
And finally here is where everything gets wired up today. Using this code, every time VendorRepository is injected, a new instance is created.
For(typeof(IRepository<>)).Use(typeof(SqlRepository<>));
For<ISessionSource>()
.Use(context => ConfigurationSettings.RunAgainstLocalDatabase
? (ISessionSource) context.GetInstance<LocalSessionSource>()
: (ISessionSource) context.GetInstance<LiveSessionSource>());
For<ISession>()
.HybridHttpOrThreadLocalScoped()
.Use(context => context.GetInstance<ISessionSource>().OpenSession());
When I tried to use a singleton here, my currentSession was being closed by NHibernate.
For(typeof(IRepository<>)).Singleton().Use(typeof(SqlRepository<>));
Edit:
I'm not entirely sure if this would work as I have a large number of repositories and entities. But I'm currently attempting to add these in by hand to test and see if it would work or not. My end goal is to have singletons of all the entity repositories (such as VendorRepository).
For<IRepository<Vendor>>()
.HybridHttpOrThreadLocalScoped()
.Use(context => new SqlRepository<Vendor>(
context.GetInstance<ISessionSource>().OpenSession()
));
Edit again:
This appears to be more accurate.. although I'm still not quite sure.
For<IVendorRepository>()
.HybridHttpOrThreadLocalScoped()
.Use(context => new VendorRepository(new SqlRepository<Vendor>(context.GetInstance<ISessionSource>().OpenSession())));
Final Edit:
Here is what needs to happen on a per repository basis. I have no idea how I can do this without listing out every repository as per below (~100). However, in limited testing, using singleton's instead of new instances for every dependency injection had no perceived performance increase. Unless there is an easier way to have StructureMap pick up the repositories and bind them automatically and correctly, I will just leave the way it is where it creates multiple instances as opposed to trying to list out ~100 nearly identical copies of the following code.
For<IVendorRepository>()
.HybridHttpOrThreadLocalScoped()
.Singleton()
.Use(context => new VendorRepository(
new SqlRepository<Vendor>(context.GetInstance<ISession>())
));
I have an extension class for a Product object.
Is there any way of injecting the service classes i need without passing them as method parameters?
public static class ProductExtensionMethods
{
public static void CalculatePrice(this Product product,
ICalculateProductPriceService _calculatePriceService,
IUnitOfWork _unitOfWork)
{
// Can I inject the unitOfWork and Service without
// passing them as parameters?
product.Price = _calculatePriceService.Calculate();
_unitOfWork.Commit();
}
}
You can't do this with any DI container afaik because although you can define a constructor on a static class, that constructor must be parameterless.
The only way I could see this working for you would be to either
define CalculatePrice on instances of Product but the instance function simply passes through the call to the static method. Inject the dependencies into the instance via constructor and pass them via the static call within the instance call.
Create a "helper" class that does the same thing (e.g ProductPriceHelper) and implement a Setup or Initialise method on it taking the dependencies, but you still will not* be able to have DI auto-inject for you - you'll have to do it manually somewhere in your composition rot (i.e wherever you currently do all your Ninject binding).
Secret door #3: I would be inclined to rearrange how your price calcuation works; I would humbly suggest that your ICalculateProductPriceService should have a method that accepts a Product instance and performs its magic therein. The ICalculateProductPriceService dependency is then injected into the Product during construction and you call a method Product.GetPrice() which invokes ICalculateProductPriceService.Calculate(this)...if you can't or won't inject the service during ctor (e.g if it is an EF entity, etc) then you can make it a required param dependency on GetPrice.
I realise that having said this someone will no doubt come up with a technically excellent workaround to allow this, but it will always be a hack...
It seems as if you are implementing use cases inside extension methods. I see no benifits for doing this over creating normal classes. So instead of using an extension method, simply make this method non-static, wrap it in an non-static class, and inject the dependencies through the constructor.
This could look like this:
public class CalculateProductPriceUseCase
{
private ICalculateProductPriceService _calculatePriceService;
private IUnitOfWork _unitOfWork;
public CalculateProductPriceUseCase(
ICalculateProductPriceService calculatePriceService,
IUnitOfWork unitOfWork)
{
_calculatePriceService = _calculatePriceService;
_unitOfWork = unitOfWork;
}
public void Handle(Product product)
{
product.Price = _calculatePriceService.Calculate();
_unitOfWork.Commit();
}
}
What still bothers me about this solution however is the Commit call. Why should the use case itself have to call commit. That seems like an infrastructure thing to me and it is easy to forget to implement this. Especially since the class doens't create the unitOfWork itself, but gets it from the outside.
Instead you can wrap this use case in a decorator that does this for you, but... if you do that, you'll need to add a proper abstraction so you can wrap all your use cases in such decorator. It could look like this:
public class CalculateProductPrice
{
public int ProductId { get; set; }
}
public class CalculateProductPriceUseCaseHandler
: IUseCase<CalculateProductPrice>
{
private ICalculateProductPriceService _calculatePriceService;
private IUnitOfWork _unitOfWork;
public CalculateProductPriceUseCaseHandler(
ICalculateProductPriceService calculatePriceService,
IUnitOfWork unitOfWork)
{
_calculatePriceService = _calculatePriceService;
_unitOfWork = unitOfWork;
}
public void Handle(CalculateProductPrice useCase)
{
var product = _unitOfWork.Products.GetById(useCase.ProductId);
product.Price = _calculatePriceService.Calculate();
}
}
Consumers can now depend on an IUseCase<CalculateProductPrice> and you can give them either an CalculateProductPriceUseCaseHandler instance, or wrap that instance in a decorator. Here's an example of such decorator:
public class TransactionUseCaseDecorator<T> : IUseCase<T>
{
private IUnitOfWork _unitOfWork;
private IUseCase<T> _decoratedInstance;
public TransactionUseCaseDecorator(IUnitOfWork unitOfWork,
IUseCase<T> decoratedInstance)
{
_unitOfWork = unitOfWork;
_decoratedInstance = decoratedInstance;
}
public void Handle(T useCase)
{
// Example: start a new transaction scope
// (or sql transaction or what ever)
using (new TransactionScope())
{
_decoratedInstance.Handle(useCase);
// Commit the unit of work.
_unitOfWork.Commit();
}
}
}
Now you have one single generic decorator that can be wrapped around any IUseCase<T> implementation.
I have the following code
public class Something {
[Inject]
public Configuration config {get;set;} //singleton
[Inject]
public Provider<WindowHandler> windowsProvider { get; set; } //NOT singleton
public void Search(string text) {
WindowHandler handler = windowsProvider.Create(xxxxxx);
//use the new handler that was created
}
}
but it seems the Provider takes an IContext where I put xxxxxx. Shouldn't the IContext from when I bootstrapped and created Something.cs from the kernel be used. Where is the no parameter Create method on the Provider??? (I am coming from Guice land point of view where it would be coded like above).
so the question is How do I do this correctly?
thanks,
Dean
It seems you are trying to use a provider as a factory in your code.
A provider in Ninject terms is a factory that is given to Ninject to create specially created objects. Therefore it gets the resolving context which can be used to create different instances depending where the instance in injected into.
public class FooProvider : Provider<IFoo>
{
public override IFoo CreateInstance(IContext ctx)
{
// add here your special IFoo creation code
return new Foo();
}
}
kernel.Bind<IFoo>().ToProvider<FooProvider>();
What you want is a factory in your coder that creates an instance of WindowHandler. Therefore create an interface to create the instance like this:
public interface IWindowHandlerFactory
{
WindowHandler Create();
}
Bind<IWindowHandlerFactory>().ToFactory();
Alternatively you can inject Func<WindowHandler> without adding a configuration. But this is less meaningful in my opinion.
NOTE: All this requires Ninject.Extensions.Factory available as prerelease 3.0.0-rc2 from Nuget.
See also: http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction/
Well, my final solution was to cheat in ninject 2.0 with the following code...
var windowFactory = kernel.Get<IEWindowFactory>();
var tabFactory = kernel.Get<IETabFactory>();
windowFactory.Kernel = kernel;
tabFactory.Kernel = kernel;
and in the bindings list I have
Bind<IEWindowFactory>().ToSelf().InSingletonScope();
Bind<IETabFactory>().ToSelf().InSingletonScope();
and after that I just start my app
var main = kernel.Get<MainForm>();
main.Start();
and of course the factories are injected where I need them in the heirarchy of that MainForm.
so I manually put the kernel when starting up and then when I bootstrap my app, naturally these factories are fields in classes with [Ninject] annotation and so they can create objects. not the cleanest until we get 3.0, but it works(and I hate the extra factory classes I have to write code for but oh well).