如何在AutoFac中使用Property Injection?

在Console应用程序中,我正在使用Log4Net,在Main方法中我得到了logger对象。 现在,我想通过让所有类inheritance自具有ILog属性并且应该由Property Injection而不是Constructor Injection设置的BaseClass来使所有类中的日志对象可用。

我正在使用AutoFac IoC容器,如何将我的日志对象注入我的每个类的Log属性?

实现这一目标的最佳/最简单方法是什么?

有没有办法自动解决类型?

以下是我的测试应用程序:

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(); // tried below but didn't inject ILog object into the Product Container.Resolve(); 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(); builder.RegisterType().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"); } } } 

在我看来,Ninject 创建的解决方案比Autofac中的属性注入要好得多。 因此,我创建了一个自定义属性,这是一个自动注入我的类的postharp方面:

 [AutofacResolve] public IStorageManager StorageManager { get; set; } 

我的方面:

 [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(); } } } 

我知道问题的答案已经给出,但我认为这是解决Autofac中自动属性注入的一种非常巧妙的方法。 也许它对将来的某个人有用。

使用属性注入 :

 builder.Register(c => LogManager.GetLogger("LoggerName")) .As(); builder.RegisterType() .PropertiesAutowired(); 

属性注入适用于Properties而不适用于Fields 。 在您的课程中,Log是一个字段而不是属性,因此它永远不会被Autofac解析。

我不想使用postharp所以我做了一个快速的解决方案,但它不会自动注入。 我是Autofac的新手,应该可以继续使用这个解决方案。

 [Serializable] [AttributeUsage(AttributeTargets.Property)] public class AutofacResolveAttribute : Attribute { } public class AutofactResolver { ///  /// Injecting objects into properties marked with "AutofacResolve" ///  /// Source object public static void InjectProperties(object obj) { var propertiesToInject = obj.GetType().GetProperties() .Where(x => x.CustomAttributes.Any(y => y.AttributeType.Name == nameof(AutofacResolveAttribute))).ToList(); foreach (var property in propertiesToInject) { var objectToInject = Autofact.SharedContainer.Resolve(property.PropertyType); property.SetValue(obj, objectToInject, null); } } } 

与此通话一起使用:

 AutofactResolver.InjectProperties(sourceObject);