Im trying to use a HTML view to string rendering class i found online. Its called PDFRender atm cause this is what it will be used for. Ive been told that its set up using Dependency Injection and that it should work out of the box.
Im not sure how to instantiate it though. Since the dependencies are supposed to be injected through the constructor.
My class constructor look like this
public PdfRender(IRazorViewEngine viewEngine, ITempDataProvider tempDataProvider, IServiceProvider serviceProvider)
{
_viewEngine = viewEngine;
_tempDataProvider = tempDataProvider;
_serviceProvider = serviceProvider;
}
And i set it up in the Startup classes ConfigureMetod() like this
// Set up Report PDF html renderer
services.AddScoped<PdfRender, PdfRender>();
Now m trying this in my code (after looking at the links example)
PdfRender pdfRender;
string iWantToBetml = pdfRender.ModelToHTML(inspection);
But i get an error (ofcourse) saying that i cant use an unassigned variable. I guess i dont understand how the DI is supposed to be used. Im assuming the idea is to give the default viewEngine, dataProvider and serviceProviders.
You just need to add a PdfRender parameter to the constructor of your controller:
public PdfRender(PdfRender pdfRender, IRazorViewEngine viewEngine, ITempDataProvider tempDataProvider, IServiceProvider serviceProvider)
{
_pdfRender = pdfRender;
_viewEngine = viewEngine;
_tempDataProvider = tempDataProvider;
_serviceProvider = serviceProvider;
}
Then you can use in in an instance method on that controller
public SomeMethod(){
string iWantToBetml = _pdfRender.ModelToHTML(inspection);
}
Note that in your controller constructor you don't necessarily need to specify all these parameters, just specify the ones that the class needs and then those will be injected in from the DI container provided their types have been registered with the DI container at startup.
Related
I have a simple AutoFac example working but now want to apply this to my web api project AND have the correct separation between the layers.
The issue I am seeing is the standard controller x "does not have a default constructor" but i am stumped so asking for advice..
I am calling RegisterApiControllers as well as RegisterControllers..
this is what I have in my DependencyInjectionContainer
public static class DependencyInjectionContainer
{
public static ContainerBuilder Builder;
public static IContainer Container;
public static void Init(Assembly mainAssembly)
{
Builder = new ContainerBuilder();
var config = GlobalConfiguration.Configuration;
RegisterTypes(mainAssembly);
Container = Builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(Container);
DependencyResolver.SetResolver(new AutofacDependencyResolver(Container));
}
private static void RegisterTypes(Assembly mainAssembly)
{
var roomBookingConnectionString = ConfigurationManager.ConnectionStrings["RoomBooking"].ConnectionString;
Builder.RegisterControllers(mainAssembly);
Builder.RegisterType<RoomRepository>().As<IRoomRepository>().WithParameter(new TypedParameter(typeof(string), roomBookingConnectionString));
Builder.RegisterType<RoomService>().As<IRoomService>();
Builder.RegisterApiControllers(mainAssembly);
Builder.RegisterFilterProvider();
}
}
I am calling this in my Global.asax.cs
DependencyInjectionContainer.Init(typeof(MvcApplication).Assembly);
One big assumption here is that this is correct...
Builder.RegisterApiControllers(mainAssembly);
edit---------------------------------------------------------------------
I have just tried moving all of the DI registrations etc in the 2 methods above back to the global.asax.cs and it works!?!?
I think its something to do with the 'RegisterApiControllers'. I am passing the calling assembly into the above init method using 'typeof(MvcApplication).Assembly'. Is there something wrong with this?
Thanks.
The RegisterApiControllers method is used by Autofac to locate the controllers.
When you do Builder.RegisterApiControllers(mainAssembly); are you sure the mainAssembly parameter is the assembly containing the controllers?
Anyway, if you have this kind of problems, you can do something like this (guessing you have a controller called RoomBookingController) :
builder.RegisterApiControllers(typeof(RoomBookingController).Assembly);
This way Autofac will locate the assembly containing your controller, no matter where it is.
I am trying to find out how I can pass the StructrueMap container to a class that I wrote that inherits from another (MS-Class).
namespace TheNamespace
{
public class DatabaseIssuerNameRegistry : ValidatingIssuerNameRegistry
{
/* **This can't be done**
public DatabaseIssuerNameRegistry(IPortalTenantManager portalTenantManager)
{
_someField= portalTenantManager;
}*/
protected override bool IsThumbprintValid(string thumbprint, string issuer)
{
//How does it work ???????????
var portalTenantManager = container.GetInstance<IPortalTenantManager>();
//Do something with the portalTenantManager
}
}
I need portalTenantManager to be the Instance that I have defined in my container in the Global.asax.
My Global Assax has these things setup:
protected void Application_Start()
{
var container = new Container();
container.Configure(x =>
{ ....
....
x.For<IPortalTenantManager>().Use<PortalTenantManager>();
});
...
...
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory(container));
...
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapApiControllerFactory(container);
...
}
Edit:
Because of the comments of #NightOwl888 I'll explain a bit further what this class does. (Hopefully explaining so why my hands are tied)
My application is able to authenticate a user with Azure Active Directory and is Multi-tenant capable. In the authentication pipeline I have the possibility to store the validation endpoints in my database instead of the default way on the web.config file. See MSDN
and this, which actually is explaining exactly what I'm doing.
So I registered my class in the web.config under the Tag issuerNameRegistry. At some point of the validation pipeline my class is instantiated and the overriden method IsThumbprintValid is beeing called. The problem is that the class registered in issuerNameRegistry expects a parameterless constructor (there it is! the constrained construction!), therefore I cannot create a constructor that would solve my problem.
Thanks for your help
It turns out that this question has been asked before on MSDN, the answer of which was provided by Travis Spencer in 2 different posts.
it is typical in my experience to have a single container and use that service- or Web-side-wide. In the startup of the service or Web app, you can create the container, register the dependencies, new up an instance of your SecurityTokenServiceConfiguration class, resolve your dependencies, use it to punch out a SecurityTokenService object, and host it.
After the first beta, we really pushed for DI support. We got a little hook in beta 2. You can now create a custom SecurityTokenServiceConfiguration class that overrides the virtual CreateSecurityTokenService method. The implementation in Microsoft's SecurityTokenServiceConfiguration does Activator.CreateInstance; yours can do IoC. This can include the resolution of an IssuerNameRegistiry. Something like this perhaps:
RequestSecurityTokenResponse Issue(IClaimsPrincipal principal, RequestSecurityToken request)
{
SecurityTokenServiceConfiguration config = new MyGoodSecurityTokenServiceConfiguration();
SecurityTokenService sts = config.CreateSecurityTokenService();
RequestSecurityTokenResponse rstr = sts.Issue(principal, request);
return rstr;
}
public class MyGoodSecurityTokenServiceConfiguration : SecurityTokenServiceConfiguration
{
public override SecurityTokenService CreateSecurityTokenService()
{
IssuerNameRegistry = IoC.Resolve<IssuerNameRegistry>();
var sts = IoC.Reslove<SecurityTokenService>();
return sts;
}
}
Of course, this means that you need to create a static instance of your DI container so it is accessible to your SecurityTokenServiceConfiguration class. Personally, I don't like that idea because it makes your DI container accessible throughout the application, which can lead to abuse of the DI container as a service locator.
Ideally, there would be a way in any DI friendly framework to pass the container into an abstract factory in order to resolve service dependencies. However, since I am not familiar with WIF it is unclear whether that can be done - perhaps the class where the Issue method exists could have a constructor added? The trick is to keep walking up the chain until you find the first place in the framework where you can intervene and do all of your DI configuration there.
I'm using Ninject in an MVC project and am trying to implement Domain Events following Udi Dahan's pattern http://www.udidahan.com/2009/06/14/domain-events-salvation/
In the extract below, the "Container" is used to resolve all the event-handlers for the particular type of event that has been raised.
My question (& apologies if I am missing something basic) is how to do this with Ninject? In other words:
How does the "Container" get set in this static class?
Once I have a Container (Kernel?) what would be the Ninject syntax to resolve all the event handlers (which I'm assuming I would have to register before-hand in a Service Module)?
I keep reading in posts that only constructor injection should be used and everything recursively get resolved from that, and that accessing the Ninject Kernel is a no-no. So any advice on how to do this will be much appreciated.
Extract from the article
public static class DomainEvents
{
[ThreadStatic] //so that each thread has its own callbacks
private static List<Delegate> actions;
public static IContainer Container { get; set; } //as before
//Registers a callback for the given domain event
public static void Register<T>(Action<T> callback) where T : IDomainEvent
{
if (actions == null)
actions = new List<Delegate>();
actions.Add(callback);
}
//Clears callbacks passed to Register on the current thread
public static void ClearCallbacks ()
{
actions = null;
}
//Raises the given domain event
public static void Raise<T>(T args) where T : IDomainEvent
{
if (Container != null)
foreach(var handler in Container.ResolveAll<Handles<T>>())
handler.Handle(args);
if (actions != null)
foreach (var action in actions)
if (action is Action<T>)
((Action<T>)action)(args);
}
}
How does the "Container" get set in this static class?
You will have to set it during application startup:
DomainEvents.Container = kernel;
what would be the Ninject syntax to resolve all the event handlers:
You can do it like this, for instance:
Container.Get<IEnumerable<Handles<T>>>())
Udi's static DomainEvents class is an implementation of the Ambient Context anti-pattern (see DI PP&P chapter 5.3). In this case I would rather use dependency injection to inject an IDomainEvents abstraction into code that needs it, instead of letting code depend on a static instance.
The problem however is that your domain objects will need a dependency on the IDomainEvents and constructor injection is (probably) not possible. The trick is to use method injection in that case.
In other words, use constructor injection to inject the IDomainEvents into command handlers or services (or what ever you call your business logic that uses the methods on your domain objects) and pass that dependency into the domain object when calling a method that needs it (method injection).
I am writing a library that will provide a collection of public types to its consumers.
I want to make types from this library dependency injection friendly. This means that every class needs to have a constructor through which it is possible to specify every single dependency of the object being initialized. I also want the library to adhere to the convention over configuration principle. This means that if a consumer wants the default behavior, he may use a parameterless constructor and the object will somehow construct the dependencies for itself.
In example (C#):
public class Samurai {
private readonly IWeapon _weapon;
// consumers will use this constructor most of the time
public Samurai() {
_weapon = ??? // get an instance of the default weapon somehow
}
// consumers will use this constructor if they want to explicitly
// configure dependencies for this instance
public Samurai(IWeapon weapon) {
_weapon = weapon;
}
}
My first solution would be to use the service locator pattern.
The code would look like this:
...
public Samurai() {
_weapon = ServiceLocator.Instance.Get<IWeapon>();
}
...
I have a problem with this, though. Service locator has been flagged as an anti-pattern (link) and I completely agree with these arguments. On the other hand, Martin Fowler advocates use of the service locator pattern exactly in this situation (library projects) (link). I want to be careful and eliminate the possible necessity to rewrite the library after it shows up that service locator really was a bad idea.
So in conclusion - do you think that service locator is fine in this scenario? Should I solve my problem in a completely different way? Any thought is welcome...
If you want to make life easier for users who are not using a DI container, you can provide default instances via a dedicated Defaults class which has methods like this:
public virtual Samurai CreateDefaultSamurai()
{
return new Samurai(CreateDefaultWeapon());
}
public virtual IWeapon CreateDefaultWeapon()
{
return new Shuriken();
}
This way you don't need to pollute the classes themselves with default constructors, and your users aren't at risk of using those default constructors unintentionally.
There is an alternative, that is injecting a specific provider, let's say a WeaponProvider in your case into your class so it can do the lookup for you:
public interface IWeaponProvider
{
IWeapon GetWeapon();
}
public class Samurai
{
private readonly IWeapon _weapon;
public Samurai(IWeaponProvider provider)
{
_weapon = provider.GetWeapon();
}
}
Now you can provide a local default provider for a weapon:
public class DefaultWeaponProvider : IWeaponProvider
{
public IWeapon GetWeapon()
{
return new Sword();
}
}
And since this is a local default (as opposed to one from a different assembly, so it's not a "bastard injection"), you can use it as part of your Samurai class as well:
public class Samurai
{
private readonly IWeapon _weapon;
public Samurai() : this(new DefaultWeaponProvider())
{
}
public Samurai(IWeaponProvider provider)
{
_weapon = provider.GetWeapon();
}
}
I have used the following approach in my C# project. The goal was to achieve dependency injection (for unit / mock testing) whilst not crippling the implementation of the code for a "normal use case" (i.e. having a large amount of new()'s that are cascaded through the execution flow).
public sealed class QueueProcessor : IQueueProcessor
{
private IVbfInventory vbfInventory;
private IVbfRetryList vbfRetryList;
public QueueProcessor(IVbfInventory vbfInventory = null, IVbfRetryList vbfRetryList = null)
{
this.vbfInventory = vbfInventory ?? new VbfInventory();
this.vbfRetryList = vbfRetryList ?? new VbfRetryList();
}
}
This allows DI but also means any consumer doesn't have to worry about what the "default instance flow" should be.
Is there a way to use Property Injection in Ninject 2 without using the [Inject] attribute? This creates a dependency to Ninject in the class that will be wired using it and I prefer to avoid having unneeded dependencies to my IoC container, that's why I end up using Constructor Injection more often.
I guess the same applies to Method Injection
I followed Ruben's tip and posted a small blog post on how to achieve this, but here's the quick answer:
Create a custom attribute:
public class InjectHereAttribute : Attribute
{
}
The target class will now look like this:
public class Samurai
{
[InjectHere]
public IWeapon Context { get; set; }
}
Now Ninject must be configured to use the custom attribute, this can be done by creating an implementation of IInjectionHeuristic that recognizes the custom attribute:
public class CustomInjectionHeuristic : NinjectComponent, IInjectionHeuristic, INinjectComponent, IDisposable
{
public new bool ShouldInject(MemberInfo member)
{
return member.IsDefined(
typeof(InjectHereAttribute),
true);
}
}
And finally add this behavior to the Ninject Kernel using the Components collection, it will run along the existing components, namely the default implementation of IInjectionHeuristic, which means either the default or the custom attribute can be used.
// Add custom inject heuristic
kernel.Components.Add<IInjectionHeuristic, CustomInjectionHeuristic>();
You can pass in another [attribute] type to the Kernel upon creation which can be used instead of InjectAttribute, but you'll still have to reference something centrally OOTB.
There was a similar question very recently about doing PI without attributes - there's no OOTB (as in directly on the fluent configuration interface) to put in a custom scanner but the extensibility points (you add a component that implements a Ninject interface as you build your Kernel that dictates how that aspect is to be work if looking for a given attribute isnt't what you want) are in there to determine where to inject based on Convention over Configuration - there's nothing stopping you amending the scanning to be based on just an attribute name (so it doesnt necessarily have to live in a central location).
Note that, in general, constructor injection is good for lots of reasons anyway, including this one, and keeping you code container agnostic is important (even if you're currently happy with one!)
I was able to accomplish this using a Heuristic class:
public sealed class MyInjectionHeuristic : NinjectComponent, IInjectionHeuristic
{
private static readonly IList<Type>
_propertyInjectible =
new List<Type>
{
typeof(IMyService),
};
/// <summary>
/// Returns a value indicating whether the specified member should be injected.
/// </summary>
/// <param name="member">The member in question.</param>
/// <returns><c>True</c> if the member should be injected; otherwise <c>false</c>.</returns>
public bool ShouldInject(MemberInfo member)
{
var info = member as PropertyInfo;
if( member == null || info == null )
return false;
if (info.CanWrite)
return _propertyInjectible.Contains(info.PropertyType);
if( this.Settings == null )
return false;
var propList = member.GetCustomAttributes(this.Settings.InjectAttribute, true);
return propList.Length > 0;
}
}
When creating your kernel:
var heuristics = _kernel.Components.Get<ISelector>().InjectionHeuristics;
heuristics.Add(new MyInjectionHeuristic());
Simple add additional types to the IList when you want to inject other types via properties.