-
-
Notifications
You must be signed in to change notification settings - Fork 122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
False positive validation error when using service setup with certain conditions #577
Comments
@Metadorius Interesting, will check. Thanks for the code. |
@Metadorius This happens to be an interesting problem. We have two logger registrations, and when calling the The resolution of the logger with condition The problem is that So in a way, You may, and probably should, narrow the roots by passing the specific list of the service types, or service info or the registration condition, like this I will add this advice to the validation error message. |
Hmm, yeah an interesting issue indeed.
I see, will check. I wonder if it's possible to exclude certain registrations from validation though, because I think right now I need to either have a big whitelist or make some validation condition (or maybe supply a "blacklist" of sorts). |
Something like: container.Register(
Made.Of(_ => ServiceInfo.Of<ILoggerFactory>(),
f => f.CreateLogger(Arg.Index<Type>(0)),
r => r.Parent.ImplementationType),
setup: Setup.With(condition: r => r.Parent.ImplementationType != null,
excludeFromValidation: true)); |
On another thought, the "validation roots whitelist" approach (if I correctly understood it) would also not work good with MEF attributed model which I use, because I don't know the service types beforehand and would need to somehow retrieve them. |
@Metadorius You may exclude via metadata or vice versa, include via metadata. |
Is this the thing? container.Register(
Made.Of(_ => ServiceInfo.Of</*ILoggerFactory*/_SerilogLoggerFactory>(),
f => f.CreateLogger(Arg.Index<Type>(0)),
r => r.Parent.ImplementationType),
setup: Setup.With(condition: r => r.Parent.ImplementationType != null,
asResolutionRoot: false)); Because when I use it - it still throws the same exception. I also don't see exclusion of |
Nope, it is not working for the Validate, which maybe confusing. Will look into it. |
Thanks much, checked it out! What I thought of: /// <summary>Excluding open-generic registrations and non-root registrations, cause you need to provide type arguments to actually create these types.</summary>
public static bool DefaultValidateCondition(ServiceRegistrationInfo reg) => !reg.ServiceType.IsOpenGeneric() && reg.AsResolutionRoot;
/// <summary>Helps to find potential problems in service registration setup. Method tries to resolve the specified registrations, collects exceptions,
/// and returns them to user. Does not create any actual service objects. You must specify <paramref name="condition"/> to define your resolution roots,
/// otherwise container will try to resolve all registrations, which usually is not realistic case to validate.</summary>
public static KeyValuePair<ServiceInfo, ContainerException>[] Validate(this IContainer container, Func<ServiceRegistrationInfo, bool> condition = null)
{
var conditionWithDefault = condition == null
? (Func<ServiceRegistrationInfo, bool>)DefaultValidateCondition
: (r => condition(r) && DefaultValidateCondition(r));
var roots = container.GetServiceRegistrations().Where(conditionWithDefault).Select(r => r.ToServiceInfo()).ToArray();
if (roots.Length == 0)
Throw.It(Error.FoundNoRootsToValidate, container);
return container.Validate(roots);
} (can PR that if you want) Reiterated on my understanding of the issue at hand, I now understand what's resolution root better, and it seems to me that it makes more sense this way, considering usually you don't have many resolution roots (tho for my application where I resolve the module pages manually this isn't the case, but generally it is) so I didn't change the default. Also the parameterless call to Edit: actually not sure, maybe it's better to have everything be resolution root by default. |
It breaks the default behavior. I would rather filter all registrations based on the IsResolutionRoot, then if nothing found fallback to the current behavior. |
Hmm you're right, not sure how to deal with it best. Either way I think that's a topic for another issue, the error explanation amendment now gives a push in the correct direction so I think we can close this issue. Thanks for the great work :) |
Same background as in #576, registering a logger factory with two resolution routes, but now another issue (I bandaid fixed one in #576 for now so ignore it in context of this issue):
Upon calling
container.ValidateAndThrow()
I am met with:It seems that the validation routine creates a resolution request with null
.Parent.ImplementationType
which makes the request to resolve the second registration ofILogger
fail because of unfulfilled condition, because if you remove the second registration's condition it is able to resolve it just fine.The text was updated successfully, but these errors were encountered: