Intereting Posts
C #: производительность ToArray Связывание наблюдаемой коллекции с ListBox в XAML Как правильно выгрузить AppDomain с помощью C #? Мониторинг реестра, в том числе доступ к реестру в режиме ядра? Могу ли я использовать язык, отличный от VBScript, для программного выполнения QTP-тестов? Слежение за скелетом Kinect Используя метод XElement.Elements, могу ли я найти элементы с подстановочным пространством имен, но с тем же именем? Страница обработчика FTP, строка вызова из справки aspx с методом для инициализации страницы обработчика Начинающие streamи в C # Как я могу получить содержимое веб-страницы и сохранить ее в строковой переменной VS Team Test: .Net Unit Testing с Excel в качестве источника данных: сбой адаптера MoreLinq maxBy против LINQ max + где Загрузка сборки, предназначенной для .NET 4.5, в домене приложений .NET 4.0 «Это выражение вызывает побочные эффекты и не будет оцениваться». Как подавить? Читайте из местоположения на консоли C #

Как использовать функцию Injection с AutoFac?

В приложении консоли я использую Log4Net, а в основном методе я получаю объект logger. Теперь я хотел бы сделать этот лог-объект доступным во всех моих classах, разрешив всем classам наследовать от BaseClass, который имеет свойство ILog и должен быть установлен с помощью Property Injection, а не с помощью Injection Constructor.

Я использую контейнер AutoFac IoC, как вставлять свой объект журнала в свойство Log каждого моего classа?

Каков наилучший / простой способ достичь этого?

Есть ли способ автоматически разрешать типы?

Ниже мое тестовое приложение:

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, созданное , намного лучше, чем propertyinjection в Autofac. Поэтому я создал настраиваемый атрибут, который является аспектом postsharp, который автоматически вводит мои classы:

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

Вложение свойств выполняется для свойств, а не для полей . В вашем classе 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);