I have added a code in my startup class (.net core 3.1) to return the type based on parameter and I get compile-time errors.
I have created a running example in sharplab. if switch expression contains the string or other objects it runs fine.
working example 1:
var x = key switch
{
"myhandler1" => "something",
"myhandler2" => "something else",
_ => "default case"
};
working example 2:
object obj = s switch {
"a" => new object(),
"b" => new DateTime(),
_ => throw new NotImplementedException()
};
Error example:
interface IHandler { }
public class BaseHandler { }
public class MyHandler1: BaseHandler, IHandler { }
public class MyHandler2: BaseHandler, IHandler { }
class Program
{
static void Main(string[] args)
{
var key = "myhandler1";
var handler = key switch
{
"myhandler1" => new MyHandler1(),
"myhandler2" => new MyHandler2(),
_ => throw new NotImplementedException()
};
var x = key switch
{
"myhandler1" => "something",
"myhandler2" => "something else",
_ => "default case"
};
Console.WriteLine("Hello World!");
}
}
original problem (needs fixing):
serviceCollection.AddTransient<Func<string, IHandler>>(sp => key =>
{
return key switch
{
Constants.Brand => sp.GetService<Handler1>(),
Constants.Series => sp.GetService<Handler2>(),
_ => throw new NotImplementedException()
};
}
found this link: https://github.com/dotnet/csharplang/issues/2728
Thanks to Pavel and Marc, below is the fix:
serviceCollection.AddTransient<Func<string, IHandler>>(sp => key =>
{
return key switch
{
Constants.Brand => (sp.GetService<Handler1>() as IHandler),
Constants.Series => (sp.GetService<Handler2>() as IHandler),
_ => throw new NotImplementedException()
};
}
You should explicitly declare a type of handler, instead of
var
In your sharplab sample both handlers implement
IHandler
interface and inheritBaseHandler
class, compiler simply doesn't know which type to use, you should tell it him explicitlyThe same is true for the dependency injection sample, you should explicitly declare a type (assuming that
Handler1
andHandler2
implementIHandler
)You can do it only for one constant, compiler is smart enough to do the rest of job for you