Closed SeriousM closed 6 years ago
I know there is a ILogService
which is used for Common.Logging, NLog and log4net wrappers, but I use Serilog in combination with SerilogAnalyzer which forbids me to use another interface type for logging than Serilog.ILogger
.
The use of another type would break the c# code analyzer.
/edit: just have seen that the ILogService
is from 4.x, I use the latest version 6.x
@SeriousM very interesting use case I'll see if I can take a look this evening. I actually haven't tried combining the two together like that.
Oh thank you very much! That'd be awesome! Populating / completing an created object is a common usecase for us.
I've implemented a populate function for existing objects:
private void populate(IInjectionScope scope, object instance)
{
var request = scope.StrategyCompiler.CreateNewRequest(instance.GetType(), 1, scope);
var members = scope.MemberInjectionSelectors.Aggregate(
Enumerable.Empty<MemberInjectionInfo>(),
(list, selector) => list.Concat(selector.GetPropertiesAndFields(instance.GetType(), scope, request))).Distinct().ToArray();
foreach (var member in members)
{
var propertyInfo = (PropertyInfo)member.MemberInfo;
object createdValue;
if (!member.IsRequired)
{
scope.TryLocate(propertyInfo.PropertyType, out createdValue, withKey: member.LocateKey);
}
else
{
createdValue = scope.Locate(propertyInfo.PropertyType, withKey: member.LocateKey);
}
propertyInfo.SetValue(instance, createdValue);
}
}
I tried to use your objects. One problem I have is that the information in MemberInjectionInfo
is empty except of the MemberInfo.
Now I need to pass in the instance to tell Grace what's the target is.
@SeriousM I took a look last night and ultimately I think the reason context.TargetInfo.InjectionType
is empty is because it's only present when the type is being injected into something (that the container knows about) and there is no way to assign it as StaticContext is created when the method is first executed.
I think what you could do instead is pass the data in through the extra data parameter in locate
public object GenerateData(DataRequest request)
{
// get injected type from request.ExtraData (is a PropertyInfo or MemberInfo)
if (locatorService.TryLocate(request.RequestedType, out object instance, new { InjectedType = injectedType }))
return instance;
return Convention.NoValue;
}
ILogger registration
container.Configure(reg =>
reg.ExportFactory<StaticInjectionContext, IInjectionContext, ILogger>((context, injectionContext) =>
LoggerFactory.GetLogger(context.TargetInfo.InjectionType ?? injectionContext.GetExtraData("InjectedType"))));
I'll be honest it's a bit hard to follow what you are trying to do with out a working sample.
I'll be honest it's a bit hard to follow what you are trying to do with out a working sample.
But you guessed pretty well!
The logger of Serilog (and NLog, log4net, etc.) can be created for a context in which the logger logs. Usually this is the class name so that one is able to determine the source of the log.
To achieve this I create the ILogger
on the fly in context with the target type.
Your suggestion was a good starting point, but now I have two problems:
I hope you can help me again?
@SeriousM you are correct the injection context is not shared through the Singleton lifestyle. That said the logic for the is in the lifestyle itself so it can be overridden. I'll see if I can put together lifestyle that does what you want to do.
Great, thank you!
Hi! I'm trying to combine Grace with SimpleFixture. My attempt is as follows:
Sorry for the code but it's the smallest example I could create.
The problem is now that
context.TargetInfo.InjectionType
is empty. I guess it's because I usePopulate
from SimpleFixture instead ofLocate
from the container instance.Is there a way to tell Grace which instance is about to get populated? I don't need SimpleFixture yet I would have the same issue if I would populate my Fixture properties myself.
Thank you @ipjohnson for Grace, it's awesome :)
/ref: #141