Last active
August 29, 2015 14:23
-
-
Save sheastrickland/e2899cd7abe61e20de69 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Fact] | |
void Main() | |
{ | |
var cb = new ContainerBuilder(); | |
cb.RegisterModule(new LoggingModule<log4net.ILog>(log4net.LogManager.GetLogger)); | |
cb.RegisterModule(new LoggingModule<Serilog.ILogger>(Serilog.Log.ForContext)); | |
cb.RegisterType<HasLogProperty>(); | |
cb.RegisterType<HasLogCtor>(); | |
var container = cb.Build(); | |
//ctor, when parent is resolved by container | |
var ctorinstance = container.Resolve<HasLogCtor>(); | |
Assert.NotNull(ctorinstance.Logger); | |
Assert.NotNull(ctorinstance.Log); | |
Assert.Equal(typeof(HasLogCtor).FullName, ctorinstance.Log.Logger.Name); | |
//properties, when parent is resolved by container | |
var propinstance = container.Resolve<HasLogProperty>(); | |
Assert.NotNull(propinstance.Logger); | |
Assert.NotNull(propinstance.Log); | |
Assert.Equal(typeof(HasLogProperty).FullName, propinstance.Log.Logger.Name); | |
//properties of existing instance (think WebForms Page / UserControl instance) | |
var existinginstance = new InstanceLogProperty(); | |
container.InjectProperties(existinginstance); | |
Assert.NotNull(existinginstance.Logger); | |
Assert.NotNull(existinginstance.Log); | |
Assert.Equal(typeof(InstanceLogProperty).FullName, existinginstance.Log.Logger.Name); | |
} | |
public class InstanceLogProperty | |
{ | |
public log4net.ILog Log { get; set; } | |
public Serilog.ILogger Logger { get; set; } | |
} | |
public class HasLogProperty | |
{ | |
public log4net.ILog Log { get; set; } | |
public Serilog.ILogger Logger { get; set; } | |
} | |
public class HasLogCtor | |
{ | |
public HasLogCtor(log4net.ILog log, Serilog.ILogger logger) | |
{ | |
Log = log; | |
Logger = logger; | |
} | |
public log4net.ILog Log { get; private set; } | |
public Serilog.ILogger Logger { get; private set; } | |
} | |
public class LoggingModule<TLogger> : Autofac.Module | |
{ | |
private readonly Func<Type, TLogger> _logFactory; | |
public LoggingModule(Func<Type,TLogger> logFactory) | |
{ | |
_logFactory = logFactory; | |
} | |
protected override void Load(ContainerBuilder builder) | |
{ | |
base.Load(builder); | |
//NOTE: this is needed due to context.IsRegistered(propertyType) check in AutowiringPropertyInjector.InjectProperties, followed by context.Resolve(propertyType) | |
builder.Register((context, parameters) => _logFactory(parameters.Named<Type>(ResolutionExtensions.PropertyInjectedInstanceTypeNamedParameter))); | |
} | |
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) | |
{ | |
var type = registration.Activator.LimitType; | |
if (HasPropertyDependencyOnLogger(type)) | |
{ | |
registration.Activated += InjectLoggerViaProperty; | |
} | |
if (HasConstructorDependencyOnLogger(type)) | |
{ | |
registration.Preparing += InjectLoggerViaConstructor; | |
} | |
} | |
private bool HasPropertyDependencyOnLogger(Type type) | |
{ | |
return type.GetProperties().Any(property => property.CanWrite && property.PropertyType == typeof (TLogger)); | |
} | |
private bool HasConstructorDependencyOnLogger(Type type) | |
{ | |
return type.GetConstructors() | |
.SelectMany(constructor => constructor.GetParameters() | |
.Where(parameter => parameter.ParameterType == typeof (TLogger))) | |
.Any(); | |
} | |
private void InjectLoggerViaProperty(object sender, ActivatedEventArgs<object> @event) | |
{ | |
@event.Context.InjectProperties(@event.Instance); | |
} | |
private void InjectLoggerViaConstructor(object sender, PreparingEventArgs @event) | |
{ | |
var type = @event.Component.Target.Activator.LimitType; | |
@event.Parameters = @event.Parameters.Union(new[] | |
{ | |
new ResolvedParameter((parameter, context) => parameter.ParameterType == typeof (TLogger), (p, i) => _logFactory(type)) | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment