Closed houseofcat closed 2 years ago
Hi @houseofcat
ASP.Net Core doesn't really have the idea of a static container. Technically you could save off the IInjectionScope to a static but I would recommend against that.
I haven't played with blazor yet but I would have thought the @inject tag would work the same.
If you can put together a simple example I'll take a look because it should just work.
Thanks for the response, when I am working on it I will post a snippit.
I am just pinging to let you know I should have a sample app for you to triage shortly, thanks for keeping the issue open.
Hi @houseofcat
Where can I find the sample?
Got somethings figured out now...
Ported Business/Structural logic to a web.api and have grace and AspNetCore 3.0 working but without key lookups.
public void ConfigureContainer(IInjectionScope scope)
{
scope.Configure(c => c.ExportInstance(new DataSource(MainConnectionString, RedisConnectionString, true)).As<IDataSource>());
}
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private IDataSource DataSource { get; set; }
public WeatherForecastController(IDataSource dataSource)
{
DataSource = dataSource;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
if (DataSource == null) throw new Exception("Dependency null");
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
^ The above is working (as in the DataSource is not null).
The following configuration and usage below does not work currently.
public void ConfigureContainer(IInjectionScope scope)
{
scope.Configure(c => c.ExportInstance(new DataSource(MainConnectionString, RedisConnectionString, true)).AsKeyed<IDataSource>("main"));
}
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
[Import(Key = "main")]
private IDataSource DataSource { get; set; }
public WeatherForecastController()
{ }
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
if (DataSource == null) throw new Exception("Dependency null");
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
So if you could lend a hint to get it working, great, if not I will have to adjust my code which isn't the end of the world.
Sorry I meant to reply to this earlier. Try putting the Import attribute on the parameter for constructor injection. You could do something more complex to setup property injection but probably the simplest solution would be to add the attribute to the constructor parameter.
Hey Ian, that's what I tried, the import one is the one failing in AspNetCore 3 - sorry I wasn't clear enough - [Import(Key = "main")]
.
The simple one (i.e. the first one) is working just fine.
Grace won't automatically inject fields or properties without being configured. Sorry just to be clear you tried the attribute directly on the parameter?
public WeatherForecastController([Import(Key = "main")]IDataSource dataSource)
{
DataSource = dataSource;
}
Holy smokes, sorry for leaving this open @ipjohnson .
I resolved the issue many moons ago, none of this is really needed now.
Hey Ian, its me - the pain again! Testing out the AspNetCore 3.0 support while waiting to use the 7.1.0 release.
Got to this point... but I am a little lost. No access to the global container? Or more likely, I missed a step/something. I hit the UnitTests to see an example/for instance in AspNetCore but couldn't find one.
So, basically, how do we...
Container.Locate<IDataSource>(withKey:"main")
...within our code after just configuring scope and using AspNetCore hosting.
I also gambled and figured since we are injecting that factory into AspNetCore hosting
@inject
might work, but I couldn't figure that out/or simply doesn't work with instances in this case.In a Blazor page, much like a Razor page, you would normally call this:
@inject IDataSource Main
Hence the idea of an immediate workaround is to find my/any global static DI Container, then simply...
public IDataSource MainDs { get; set; } => Container.Locate<IDataSource>(withKey:"main")
...but again I need a specific instance to pull out. Just hoping you could give me some hints on if I can proceed this way and possibly how!
Thanks for all your hard work, I know this is all cutting edge tech stack. I understand if its just out of scope at this time.
Tristan