Intereting Posts
Могу ли я привязать элемент управления WPF к свойству поля? Automapper: преобразование JSON в список объектов Доступ к константам и структурам Windows API для P / Invoke Настройка культуры (en-IN) Глобально в приложении WPF общая функция с ограничением «имеет свойство X»? Включение анализа кода Microsoft в проектах .NET Core datagrid получить индекс ячейки Есть ли плагин Breakpoint для Visual Studio? Usinq Linq для выбора элементов, которые находятся в строке, разделенной запятыми? Как сериализовать несколько объектов в существующий XmlDocument, не имея пространства имен на каждом компоненте? Функция WPF Flowdocument «изменить регистр» Почему элементы управления пользовательским интерфейсом в WPF имеют привязку к streamу? Регулярное выражение для соответствия символу, но не тогда, когда оно заключено в квадратную скобку Не удалось загрузить файл или сборку ” или одну из его зависимостей Изменение страtagsи генерации кода EF 6 с T4

Как использовать функцию 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);