ASP.NET 5 Non-Controller DI injection - asp.net-core

I am trying to use the new ASP.NET 5 dependency injection system, but it seems limited to ONLY constructors of classes that inherit from Controller.
Is there any other way to inject things? Properties? Anything? This is so severely limiting and has had me brickwalling for days.

Just tested this (RC1 Update1), it works with other classes as well.
I wrote a small example, first the type declarations:
public interface IBaseServiceType { }
public interface IComposedServiceType
{
IBaseServiceType baseService { get; }
}
public class BaseServiceImplementation : IBaseServiceType { }
public class ComposedServiceImplementation : IComposedServiceType
{
public IBaseServiceType baseService { private set; get; }
public ComposedServiceImplementation(IBaseServiceType baseService)
{
this.baseService = baseService;
}
}
The configuration:
services.AddTransient(typeof(IBaseServiceType), typeof(BaseServiceImplementation));
services.AddTransient(typeof(IComposedServiceType), typeof(ComposedServiceImplementation));
And create the instance like this where context is your HttpContext:
var composedServiceInstance = context.ApplicationServices.GetService<IComposedServiceType>();

Register your class as a service and treat it like you would all other services
see
Net Core Dependency Injection for Non-Controller

Related

Is it bad style to inject IConfigurationRoot into a class of the business logic- or data access-layer?

We have an ASP.NET Core 1.1 application which is splitted in 3 layers:
Web
Business Logic (BLL)
Data Access (DAL)
There we have some methods of the BLL and some of the DAL that need some values from the config. I see two possibilities to pass them the required values:
define the values as parameters of the method, get them in the web-layer and pass them to the BLL and DAL
inject IConfigurationRoot to the BLL and DAL
Which of the both possibilities is more recommendable?
With ASP.NET Core you should actually choose the third possibility:
use strongly typed settings injected with IOptions<T> wrapper.
Here is a sample:
POCO for the settings:
public class SomeSettings
{
public string SomeStringValue { get; set; }
public int SomeNumericValue { get; set; }
// ...
}
Injecting the settings:
public class SomeClass
{
private readonly SomeSettings settings;
public SomeClass(IOptions<SomeSettings> options)
{
this.settings = options.Value;
}
}
Registering the settings:
public void ConfigureServices(IServiceCollection services)
{
// ...
services.Configure<SomeSettings>(Configuration.GetSection("SectionNameHere"));
}
Using Options pattern is recommended way to deal with configuration in .NET Core.

How to resolve EF7 current database context in ASP NET 5 out of the controller?

I want to get one context per request in ASP NET 5/EF 7 app for use it in some methods (not in controller).
Unfortunately I did not find the answer in the documentation
ASP.NET vNext template and examples aspnet/MusicStore
You may use some methods for achieving this purpose.
Using .AddDbContext<ApplicationDbContext>(); method for registering ApplicationDbContext in Dependency Injection system (in ConfigureServices() method), leads to the fact that it registered as Scoped dependence(or in another words "per request"). Thereby you only need get it from Dependency Injection system.
Add your dbContext as parameter of constructor method your class (in which you will use dbContext). Then you have to get this class using Dependency Injection system, e.g added it as parameter of controller's constructor.
public class HabitsController : Controller
{
public HabitsController(HabitService habitService)
{
}
}
public class HabitService
{
private GetHabitsContext _dbContext;
public HabitService(GetHabitsContext dbContext)
{
_dbContext = dbContext;
}
}
But if you don't want to use constructor injection for getting context, you can get necessary dependenses using GetService() method (but you need in ServiceProvider instance for that, in example below, i'am getting it through constructor injection too).
using Microsoft.Framework.DependencyInjection; // for beta 6 and below
using Microsoft.Extensions.DependencyInjection; // for beta 7 and above
public class HabitService
{
private IServiceProvider _serviceProvider;
public HabitService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public GetHabit()
{
var dbcontext = _serviceProvider.GetService<ApplicationDbContext>();
}
}
In first method, we can get HabitService through GetService() method too (not through the constructor injection).
using Microsoft.Framework.DependencyInjection; // for beta 6 and below
using Microsoft.Extensions.DependencyInjection; // for beta 7 and above
public class HabitsController : Controller
{
public HabitsController(IServiceProvider serviceProvider)
{
var habitService= serviceProvider.GetService<HabitService>();
}
}
public class HabitService
{
private GetHabitsContext _dbContext;
public HabitService(GetHabitsContext dbContext)
{
_dbContext = dbContext;
}
}
Thanks Tseng for remark:
I should be noted, that it's a pretty bad practice to inject the container into your objects. The container should only be referenced from the composition root and certain type of factories (which are implemented on application level, and not in the domain/business layer)
dbContext in HabitsController and _dbContext in HabitService are different contexts!
I checked, this is the same context.

Inject dependency in IStartupTask for bootstrapper

I am using Bootstrapper and Ninject to manage bootstrapping my application and dependency injection. This is an asp.net webapi application.
I have a simple implementation for IStartupTask like follows. The implementation of the ILog is been registered using Ninject. I want to know if there is a way to inject the ILog to the ContextBootstrap class?
public class ContextBootstrap : IStartupTask
{
public ILog Log { get; set; }
public ContextBootstrap(ILog log)
{
Log = log;
}
public void Run()
{
Log.Info("somehting");
}
public void Reset()
{
// do something here
}
}
I think IStartupTask internally uses the registered DI container to create instance of the concrete class, so the dependencies are injected via constructor.

How to avoid Custom type name clash generated in WCF Client

A custom type (e.g. Engine) is defined in two different namespaces on WCF server side, which is exposed to WCF client as Engine, Engine1. How to set up so that the exposed types have the same name, Engine in this case.
Below is my example code:
namespace WcfServiceLibrary1
{
[ServiceContract]
interface ICar
{
[OperationContract]
void RepairMotorCycle(MotorCycle motorCycle);
[OperationContract]
void RepairTwoDoorCar(TwoDoorCar Car);
}
public class Car:ICar
{
public void RepairMotorCycle(MotorCycle motorCycle)
{
throw new NotImplementedException();
}
public void RepairTwoDoorCar(TwoDoorCar Car)
{
throw new NotImplementedException();
}
}
}
namespace WcfServiceLibrary1.MC
{
public class MotorCycle
{
public Engine Engine { get; set; }
}
public class Engine { }
}
namespace WcfServiceLibrary1.C
{
public class TwoDoorCar
{
public Engine Engine { get; set; }
}
public class Engine { }
}
Below is the WCF client for Engine:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="Engine", Namespace="http://schemas.datacontract.org/2004/07/WcfServiceLibrary1.MC")]
[System.SerializableAttribute()]
public partial class Engine : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="Engine", Namespace="http://schemas.datacontract.org/2004/07/WcfServiceLibrary1.C")]
[System.SerializableAttribute()]
public partial class Engine1 : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
}
Please note that both MotoCycle and TwoDoorCar contain a large number of custom type that have the same name but different function. Thus, it is tedious to change the name on client side (e.g. change Engine1 to Engine for all occurences). Also it is tedious to solve it by using class inheritance. It is ok to define two custom types that have the same name, which might need less work.
Any idea would be very much appreciated!
Edit
*Possible Solution*
Put it into separate interface, as below
[ServiceContract]
interface ICar1
{
[OperationContract]
void RepairMotorCycle(MotorCycle motorCycle);
}
[ServiceContract]
interface ICar2
{
[OperationContract]
void RepairTwoDoorCar(TwoDoorCar Car);
}
This will put the same custom type in different namespace on client side.
If your Engines represent an identical concept, you could define one Engine in a dedicated namespace and reference it from WcfServiceLibrary1.MCand WcfServiceLibrary1.C.
Your example however suggests that you should rather gather your vehicles into a single namespace and make use of inheritance.
namespace WcfServiceLibrary.Vehicles
{
public class Engine
{
}
public abstract class Vehicle
{
public Engine { get; set; }
}
public class Car : Vehicle
{
}
pulic class Motorcycle : Vehicle
{
}
}
Moving your Engine to a common namespace could look like this:
namespace WcfServiceLibrary.Common
{
public class Engine
{
}
}
Your "Motorcycle" library
using WcfServiceLibrary.Common
namespace WcfServiceLibrary.MC
{
public class Motorcycle
{
public Engine Engine { get; set; }
}
}
... and your "Car" library
using WcfServiceLibrary.Common
namespace WcfServiceLibrary.C
{
public class Car
{
public Engine Engine { get; set; }
}
}
You won't have to change your Engine property.
First of all, try and share your code libraries between the server and client. This link will tell you how to do it for Silverlight, if you are not using Silverlight then check this SO search link for a variety of posts and answers on the subject.
Secondly, if you cannot share the libraries then editing the generated client class files will work (just delete the definition of Engine1 and fix up any references to it to point to the Engine), although you will lose the changes if you regenerate the proxy.

Avoiding Service Locator with AutoFac 2

I'm building an application which uses AutoFac 2 for DI. I've been reading that using a static IoCHelper (Service Locator) should be avoided.
IoCHelper.cs
public static class IoCHelper
{
private static AutofacDependencyResolver _resolver;
public static void InitializeWith(AutofacDependencyResolver resolver)
{
_resolver = resolver;
}
public static T Resolve<T>()
{
return _resolver.Resolve<T>();
}
}
From answers to a previous question, I found a way to help reduce the need for using my IoCHelper in my UnitOfWork through the use of Auto-generated Factories. Continuing down this path, I'm curious if I can completely eliminate my IoCHelper.
Here is the scenario:
I have a static Settings class that serves as a wrapper around my configuration implementation. Since the Settings class is a dependency to a majority of my other classes, the wrapper keeps me from having to inject the settings class all over my application.
Settings.cs
public static class Settings
{
public static IAppSettings AppSettings
{
get
{
return IoCHelper.Resolve<IAppSettings>();
}
}
}
public interface IAppSettings
{
string Setting1 { get; }
string Setting2 { get; }
}
public class AppSettings : IAppSettings
{
public string Setting1
{
get
{
return GetSettings().AppSettings["setting1"];
}
}
public string Setting2
{
get
{
return GetSettings().AppSettings["setting2"];
}
}
protected static IConfigurationSettings GetSettings()
{
return IoCHelper.Resolve<IConfigurationSettings>();
}
}
Is there a way to handle this without using a service locator and without having to resort to injecting AppSettings into each and every class? Listed below are the 3 areas in which I keep leaning on ServiceLocator instead of constructor injection:
AppSettings
Logging
Caching
I would rather inject IAppSettings into every class that needs it just to keep them clean from the hidden dependency on Settings. Question is, do you really need to sprinkle that dependency into each and every class?
If you really want to go with a static Settings class I would at least try to make it test-friendly/fakeable. Consider this:
public static class Settings
{
public static Func<IAppSettings> AppSettings { get; set; }
}
And where you build your container:
var builder = new ContainerBuilder();
...
var container = builder.Build();
Settings.AppSettings = () => container.Resolve<IAppSettings>();
This would allow to swap out with fakes during test:
Settings.AppSettings = () => new Mock<IAppSettings>().Object;
Now the AppSettings class (which I assume there is only one of) you could do with regular constructor injection. I assume also that you really want to do a resolve on each call to your settings properties, thus injecting a factory delegate that retrieves an instance when needed. If this is not needed you should of course inject the IConfigurationSettings service directly.
public class AppSettings : IAppSettings
{
private readonly Func<IConfigurationSettings> _configurationSettings;
public AppSettings(Func<IConfigurationSettings> configurationSettings)
{
_configurationSettings = configurationSettings;
}
public string Setting1
{
get
{
return _configurationSettings().AppSettings["setting1"];
}
}
public string Setting2
{
get
{
return _configurationSettings().AppSettings["setting2"];
}
}
}