Question

We have a standard class that looks like this:

public class AccountService : IAccountService
{
    private readonly IRepository<Account> _accountRepo;

    public AccountService(IRepository<Account> accountRepo)
    {
        if ((_accountRepo = accountRepo) == null) throw new ArgumentNullException("accountRepo");
    }
}

IRepository<T> is implemented elsewhere and accepts an Entity Framework object context. This is the component I want to override, but only for services in a specific namespace. This was my first naive attempt:

builder.RegisterAssemblyTypes(typeof(OurObjectContext).Assembly)
    .InNamespace("Company.Core.Services")
    .AsImplementedInterfaces()
    .InstancePerHttpRequest()
    .WithParameter(new ResolvedParameter((parameterInfo, componentContext) =>
    {        
        return true;

    }, (parameterInfo, componentContext) =>
    {
        return null;
    }));

But this is for the service, not the repository. How do I tell Autofac, "when you create this service for me, I want you to use that object context over there instead of the normal one for each repository you create".

How can I do this? Am I on the right track?

Était-ce utile?

La solution

Yes, you're close. Here's a sample code with comments on how it could look like:

builder.RegisterAssemblyTypes(typeof(OurObjectContext).Assembly)
    .InNamespace("Company.Core.Services")
    .AsImplementedInterfaces()
    .InstancePerHttpRequest()
    .WithParameter(new ResolvedParameter((parameterInfo, componentContext) =>
    {
        // in predicate we select only IRepository<> types
        return parameterInfo.ParameterType.GetGenericTypeDefinition() == typeof(IRepository<>);

    }, (parameterInfo, componentContext) =>
    {
        // firstly we get a generic parameter type 
        var genericArgument = parameterInfo.ParameterType.GetGenericArguments()[0];
        // then we construct a new generic type with the parameter, suppose it's LoggingRepository<> and it's registered
        var typeToResolve = typeof(LoggingRepository<>).MakeGenericType(genericArgument);

        // resolve the type and Autofac will put it instead of IRepository<>
        return componentContext.Resolve(typeToResolve);
    }));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top