Skip to content
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

Error thrown on method Import with key #298

Open
XanNava opened this issue Nov 5, 2022 · 5 comments
Open

Error thrown on method Import with key #298

XanNava opened this issue Nov 5, 2022 · 5 comments

Comments

@XanNava
Copy link

XanNava commented Nov 5, 2022

The fallowing is the coding I am using (note the different commented out elements to test behaviors are working properly in other ways).

// See https://aka.ms/new-console-template for more information

using Grace.DependencyInjection;
using Grace.DependencyInjection.Attributes;

DependencyInjectionContainer container = new DependencyInjectionContainer((c) => {
	c.AutoRegisterUnknown = true;
	c.Trace = (s => {
		Console.WriteLine(s);
	});
});

container.Configure((c) => {
	c.Export<Service>().AsKeyed<IService>("ServiceM");

	c.Export<ServiceAlt>().AsKeyed<IService>("ServiceA");

	// Will default to this if a key import fails.
	// Allows for the default [import()].
	//c.Export<Service>().As<IService>();
});

var scope = container.BeginLifetimeScope("RootScope");

var alt = container.Locate<IService>(withKey: "ServiceA");
var service = container.Locate<ServiceMain>();

Console.WriteLine(service.Service.GetString());

interface IService {
	string GetString();
}

class Service : IService {
	public virtual string GetString() {
		return "Service";
	}
}

class ServiceAlt : IService {
	public string GetString() {
		return "Service AlternativeService";
	}
}

class ServiceMain {
	// Works.
	//[Import(Key = "ServiceA")]
	public IService Service { get; set; }

	// Works with export "c.Export<Service>().As<IService>();"
	//[Import()]
	
	// Throws error that type reference in Grace is null.
	[Import(Key = "ServiceA")]
	public void Recieve(IService service) {
		Console.WriteLine("Import through method");
		Service = service;
	}
}

The above throws the fallowing error.

Unhandled exception. Grace.DependencyInjection.Exceptions.LocateException: Could not locate Type IService
1 Importing ServiceMain
2 Importing IService  for method Recieve parameter service

   at Grace.DependencyInjection.Impl.InjectionContextValueProvider.GetValueFromInjectionContext[T](IExportLocatorScope locator, StaticInjectionContext staticContext, Object key, IInjectionContext dataProvider, Object defaultValue, Boolean useDefault, Boolean isRequired)
   at lambda_method2(Closure , IExportLocatorScope , IDisposalScope , IInjectionContext )
   at Grace.DependencyInjection.Impl.ActivationStrategyDelegateCache.FallbackExecution(ImmutableHashTree`2 currentNode, Type type, IExportLocatorScope scope, Boolean allowNull, IInjectionContext context)
   at Grace.DependencyInjection.Impl.ActivationStrategyDelegateCache.ExecuteActivationStrategyDelegate(Type type, IExportLocatorScope scope)
   at Grace.DependencyInjection.Impl.BaseExportLocatorScope.Locate[T]()
   [My code url]/Program.cs:line 25

Grace version 8.0.0-Beta822

@XanNava XanNava changed the title Error on reference for type Import with key on method Error thrown on Import with key on method Nov 5, 2022
@XanNava XanNava changed the title Error thrown on Import with key on method Error thrown on method Import with key Nov 5, 2022
@XanNava
Copy link
Author

XanNava commented Nov 6, 2022

So I made a fork of the repo and it looks like the key isn't getting passed into the fallowing method it is just null. InjectionContextValueProvider.GetValueFromInjectionContext<T>(....)

If I set the key manually key = (object)"ServiceA"; the path to call GetValueFromExtraDataProvider<T>(...) is taken, but there is still an issue that the fallowing two calls in the method return null.
InjectionContext.GetExtraData(object key) <-- Method
_extraDataProperties.GetValueOrDefault(stringKey) <-- Call in method
_extraDataValues.GetValueOrDefault(key)<-- Call in method

@XanNava
Copy link
Author

XanNava commented Nov 6, 2022

https://github.com/XanNava/GraceTests
You can see my tests by cloning the above fork. Note I removed .net FrameWork 4.5 from the build target just to get it running on my pc. Run GraceTests.ConsoleApp for Method logging.

@XanNava
Copy link
Author

XanNava commented Nov 6, 2022

The IExportLocatorScope locator argument for InjectionContextValueProvider.GetValueFromInjectionContext<T>(....) Is correct, and can be used to locate the service by the key.

@XanNava
Copy link
Author

XanNava commented Nov 6, 2022

Still not sure why the key isn't being passed in, but the call GetValueFromExtraDataProvider<T>(key, currentLocator, out value) seems to not be working properly and where the method call ends and value is still null if there is a key value. I have narrowed the issue down to seemingly the two fallowing things.

  1. Key not being passed into InjectionContextValueProvider.GetValueFromInjectionContext<T>(...)
  2. IExtraDataContainer.GetExtraData(key); not returning object, but IExportLocatorScope.locate<T>(withKey: key); will. Looks like IExtraDataContainer is getting cast incorrectly from IExportLocatorScope.

@ipjohnson
Copy link
Owner

It looks like there was an issue in the auto configuration code that wasn't checking attributes on the method parameters.

I've released an updated version 8.0.0-RC824.

Note you need to specify the import on the parameter as well as the method

  class ServiceMain
  {
      public IService Service { get; set; }
      
      [Import]
      public void Recieve([Import(Key = "ServiceA")]IService service)
      {
          Console.WriteLine("Import through method");
          Service = service;
      }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants