Open atresnjo opened 5 years ago
Hey! 👋
You should be able to register using this pattern:
Hey! 👋
You should be able to register using this pattern:
Hey! Thanks for the help. But sadly that didnt work. I think I am missing something, but with that pattern how is scrutor supposed to know which DTOs to register?
Just look at the registrations in the services
collection. It should be registered as IRequestHandler<,>
, so you need to resolve IRequestHandler<GetOneByIdRequest<ApplicationUser>, ApplicationUser>
.
If you want it registered as itself, you can use services.AddScoped(typeof(GetOneByIdHandler<>));
Just look at the registrations in the
services
collection. It should be registered asIRequestHandler<,>
, so you need to resolveIRequestHandler<GetOneByIdRequest<ApplicationUser>, ApplicationUser>
.
I checked the services collection and only the generic handler GetOneByIdHandler is missing. Other non-generic handlers are added.
Ah, I think I know what's happening now. Because GetOneByIdHandler<T>
and IRequestHandler<in TRequest, TResponse>
have different generic arity, the type is filtered out when trying to register using .AsImplementedInterfaces()
.
You either have to add .AsSelf()
in addition, or just register the type explicitly, like this:
services.AddScoped(typeof(GetOneByIdHandler<>));
They should both end up doing the same (wrt. this specific type).
Ah, I think I know what's happening now. Because
GetOneByIdHandler<T>
andIRequestHandler<in TRequest, TResponse>
have different generic arity, the type is filtered out when trying to register using.AsImplementedInterfaces()
.You either have to add
.AsSelf()
in addition, or just register the type explicitly, like this:services.AddScoped(typeof(GetOneByIdHandler<>));
They should both end up doing the same (wrt. this specific type).
Sadly not. ✌️ The IRequestHandler implementations which can be seen in the second screenshot are missing.
"Message": "Handler was not found for request of type MediatR.IRequestHandler
2[KKH.MedDelivery.Application.Commands.Core.Requests.GetOneByIdRequest
1[KKH.MedDelivery.Domain.MedicalPartner],KKH.MedDelivery.Domain.MedicalPartner]. Register your handlers with the container. See the samples in GitHub for examples."
Adding with scrutor:
Adding manually:
Hello. I am trying to do something very similar. @atresnjo, did you ever figure this out?
Hello. I am trying to do something very similar. @atresnjo, did you ever figure this out?
Hey @Chris-ZA
Sorry. I never figured it out. So if you ever figure it out feel free to post! :) thanks.
@Chris-ZA / @atresnjo , did you consider using this native dependency injection package instead of scanning with Scrutor?
Encountered similar issue while trying to register open generic via Scan
.
Using interfaces like that:
public interface ISingleton { }
public interface IAppCache<out TService>{}
public class AppCache<TService>: IAppCache<TService>, ISingleton {}
and registering via:
services.Scan(scan => scan.FromAssemblyOf<ISingleton>().AddClasses(c => c.AssignableTo<ISingleton>()).AsSelfWithInterfaces().WithSingletonLifetime())
trying to fetch the service:
provider.GetRequiredService<IAppCache<object>>()
doesn't work.
Version 3.3.0. Does Scrutor really support open generics?
Does Scrutor really support open generics?
Absolutely, there a lots of tests in this repo showing that it works 😅
Absolutely, there a lots of tests in this repo showing that it works 😅
Got it. Looks like I will need to dig deeper to the source code to figure out why my case doesn't wan't to 🙂
@alexb5dh , have you seen my post above? Have you considered using that package instead of manually registering the handlers?
@julealgon unfortunately my case is not related to MediatR only, but to custom services also, one of which is provided in the example.
Encountered similar issue while trying to register open generic via
Scan
.Using interfaces like that:
public interface ISingleton { } public interface IAppCache<out TService>{} public class AppCache<TService>: IAppCache<TService>, ISingleton {}
and registering via:
services.Scan(scan => scan.FromAssemblyOf<ISingleton>().AddClasses(c => c.AssignableTo<ISingleton>()).AsSelfWithInterfaces().WithSingletonLifetime())
trying to fetch the service:
provider.GetRequiredService<IAppCache<object>>()
doesn't work.
Version 3.3.0. Does Scrutor really support open generics?
Try to use AsImplementedInterfaces
, I think your sample does not work because of AsSelfWithInterfaces
lifecycle constraints. You cannot create a single instance of one type that will cover open generic types. See #84
For example, seems the next test works as expected, besides the fact that there will be separate instances of singleton per every exposed type/interface.
[Fact]
public void Issue96_()
{
var sp = ConfigureProvider(sc =>
{
sc.Scan(scan
=> scan
.FromAssemblyOf<ISingleton>()
.AddClasses(c => c.AssignableTo<ISingleton>())
.AsImplementedInterfaces()
.WithSingletonLifetime());
});
var result = sp.GetService<IAppCache<object>>();
Assert.NotNull(result);
Assert.IsAssignableFrom<AppCache<object>>(result);
}
any update?
eg:
ConcreteClass
I wonder if this is the same bug as https://github.com/khellang/Scrutor/issues/104?
Hi. I have a generic mediatr request handler which looks like this:
Right now I have to add the handler for every DTO manually. How can I automate this with Scrutor? Thanks!
services.AddTransient<IRequestHandler<GetOneByIdRequest<MyDto>, MyDto>, GetOneByIdHandler<MyDto>>();