In a Console application, I'm using Log4Net and in the Main method I'm getting the logger object. Now, I'd like to make this log object available in all my classes by letting all the classes inherit from a BaseClass which has a ILog property and is supposed to be set by Property Injection rather than Constructor Injection.
I'm using AutoFac IoC container, how to inject my log Object to the Log property of my every class?
What's the best/easiest way to achieve this?
Is there any way to automatically resolve types?
Below is my test application:
namespace ConsoleApplication1 { class Program { static ILog Log; static IContainer Container; static void Main(string[] args) { InitializeLogger(); InitializeAutoFac(); // the below works but could it be done automatically (without specifying the name of each class)? Product.Log = Container.Resolve<ILog>(); // tried below but didn't inject ILog object into the Product Container.Resolve<Product>(); RunTest(); Console.ReadLine(); } private static void RunTest() { var product = new Product(); product.Do(); } private static void InitializeAutoFac() { var builder = new ContainerBuilder(); builder.Register(c => Log).As<ILog>(); builder.RegisterType<Product>().PropertiesAutowired(); Container = builder.Build(); } private static void InitializeLogger() { log4net.Config.XmlConfigurator.Configure(); Log = LogManager.GetLogger("LoggerName"); } } public class Product { public static ILog Log { get; set; } public void Do() { // this throws exception because Log is not set Log.Debug("some Debug"); } } }
In property injection, we need to pass object of the dependent class through a public property of the client class. Let's use the below example for the implementation of the Property Injection or even it is called Setter Injection as value or dependency getting set in property.
Constructor injection should be the main way that you do dependency injection. It's simple: A class needs something and thus asks for it before it can even be constructed. By using the guard pattern, you can use the class with confidence, knowing that the field variable storing that dependency will be a valid instance.
Property injection is a type of dependency injection where dependencies are provided through properties. Visit the Dependency Injection chapter to learn more about it. Let's understand how we can perform property injection using Unity container. Consider the following example classes. Example: C#
In my opinion the solution Ninject created is much nicer than the propertyinjection in Autofac. Therefore I created a a custom attribute which is a postsharp aspect which automatically injects my classes:
[AutofacResolve] public IStorageManager StorageManager { get; set; }
My aspect:
[Serializable] [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public class AutofacResolveAttribute : LocationInterceptionAspect { public override void OnGetValue(LocationInterceptionArgs args) { args.ProceedGetValue(); if (!args.Location.LocationType.IsInterface) return; if ( args.Value != null ) { args.Value = DependencyResolver.Current.GetService(args.Location.LocationType); args.ProceedSetValue(); } } }
I know the answer on the question is already given but I thought this was a really neat way of solving automatic property injection in Autofac. Maybe it'll be useful to somebody in the future.
Use Property Injection:
builder.Register(c => LogManager.GetLogger("LoggerName")) .As<ILog>(); builder.RegisterType<CustomClass>() .PropertiesAutowired();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With