You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm using Lamar for DI and the IHostBuilder.OverrideServices method to introduce fakes/mocks during integration testing which works fine until I want to replace a named instance.
As soon as I add a named instance in OverrideServices that is already registered elsewhere, I get the following error:
System.InvalidOperationException
HResult=0x80131509
Message=Referenced instance of Company.DbRepository.Interfaces.IDbRepository named 'AlreadyRegisteredName' does not exist
Source=Lamar
StackTrace:
at Lamar.IoC.Instances.ReferencedInstance.<createPlan>d__10.MoveNext()
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
at Lamar.IoC.Instances.Instance.CreatePlan(ServiceGraph services)
at Lamar.IoC.Instances.ConstructorInstance.buildOutConstructorArguments(ServiceGraph services)
at Lamar.IoC.Instances.ConstructorInstance.createPlan(ServiceGraph services)
at Lamar.IoC.Instances.Instance.CreatePlan(ServiceGraph services)
at Lamar.IoC.Instances.ConstructorInstance.buildOutConstructorArguments(ServiceGraph services)
at Lamar.IoC.Instances.ConstructorInstance.createPlan(ServiceGraph services)
at Lamar.IoC.Instances.Instance.CreatePlan(ServiceGraph services)
at Lamar.IoC.Instances.ConstructorInstance.buildOutConstructorArguments(ServiceGraph services)
at Lamar.IoC.Instances.ConstructorInstance.createPlan(ServiceGraph services)
at Lamar.IoC.Instances.Instance.CreatePlan(ServiceGraph services)
at Lamar.ServiceGraph.planResolutionStrategies()
at Lamar.ServiceGraph.buildOutMissingResolvers()
at LamarCodeGeneration.Util.PerfTimer.Record(String text, Action action)
at Lamar.ServiceGraph.Initialize(PerfTimer timer)
at Lamar.IoC.Scope..ctor(IServiceCollection services, PerfTimer timer)
at Lamar.Container..ctor(IServiceCollection services)
at Lamar.Microsoft.DependencyInjection.LamarServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder)
at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
at Microsoft.Extensions.Hosting.HostBuilder.Build()
at Company.Integration.Orchestrator.IntegrationsOrc.Program.Main(String[] args) in C:\Repos\integration-orc-service\Clients\IntegrationsOrc\Program.cs:line 64
I'm unsure if this has any relevance, but we're using a policy to reference the correct registered name when resolving the IDbRepository (and use an Attribute on the IDbRepository parameter to specify the name to resolve to)
public class NamedInstancePolicy<T> : ConfiguredInstancePolicy
{
/// <inheritdoc/>
protected override void apply(IConfiguredInstance instance)
{
foreach (var param in instance.ImplementationType.GetConstructors()
.SelectMany(x => x.GetParameters())
.Where(x => x.ParameterType == typeof(T)))
{
// Primary route is to resolve the instance based on a custom attribute
var ipAttribute = param.GetCustomAttribute<InstancePolicyNameAttribute>();
if (ipAttribute == null)
{
// The IDbConnection parameter was not marked with the correct attribute
throw new InvalidOperationException($"A {param.ParameterType.Name} parameter in {instance.Name} does not contain the required InstancePolicyNameAttribute to define which instance should be resolved.");
}
// Parameter was correctly set up, assign the named instance to the constructor parameter
instance.Ctor<T>(param.Name).IsNamedInstance(ipAttribute.InstanceName);
}
}
}
I'm using the latest version of Lamar (8.0.1) and asp.net core 6.0.
This same error occurs if I register the same type with the same name twice. Any ideas how to resolve this? Maybe I could remove the previous named registration somehow (I'd need a way to do that within the OverrideServices method)?
The text was updated successfully, but these errors were encountered:
Did you find a solution for this? I've run into the same issue with named registrations.
I don't know if this works when using builder.OverrideService()...., but generally this is what work's for us:
/// <summary>/// Registers the given instance with the given namen and removes the last already available registration for this type and with this name./// </summary>/// <param name="instance">The instance which should be registered with the given name.</param>/// <param name="name">The name of the registration.</param>/// <typeparam name="TType">The type of the given instance.</typeparam>/// <param name="serviceRegistry">The service registry is needed to remove already existing registrations.</param>publicstaticTTypeOverrideNamed<TType>(thisTTypeinstance,stringname,ServiceRegistryserviceRegistry)whereTType:Instance{if(instance==null)thrownewArgumentNullException(nameof(instance));if(string.IsNullOrWhiteSpace(name))thrownewArgumentException(@"Value cannot be null or whitespace.",nameof(name));if(serviceRegistry==null)thrownewArgumentNullException(nameof(serviceRegistry));serviceRegistry.RemoveAll(serviceDescriptor =>serviceDescriptor.ServiceType==instance.ServiceType&&serviceDescriptor.ImplementationInstanceisInstancecurrentInstance&¤tInstance.Name.Equals(name,StringComparison.OrdinalIgnoreCase));instance.Named(name);returninstance;}
I'm using Lamar for DI and the
IHostBuilder.OverrideServices
method to introduce fakes/mocks during integration testing which works fine until I want to replace a named instance.As soon as I add a named instance in OverrideServices that is already registered elsewhere, I get the following error:
I'm unsure if this has any relevance, but we're using a policy to reference the correct registered name when resolving the
IDbRepository
(and use an Attribute on theIDbRepository
parameter to specify the name to resolve to)I'm using the latest version of Lamar (8.0.1) and asp.net core 6.0.
This same error occurs if I register the same type with the same name twice. Any ideas how to resolve this? Maybe I could remove the previous named registration somehow (I'd need a way to do that within the OverrideServices method)?
The text was updated successfully, but these errors were encountered: