Power Star
Power Star

Reputation: 1894

Autofac TypedParameter equivalent in NET Core DI

I'm migrating .NET framework projects into .NET 6. We are using Autofac for DI in .NET Framework projects and looking forward to move MS.DI. In the existing project there is a way to pass constructor params while resolving the object in run time, I m looking for a way to do the same in MS DI.

Example:

public interface IMemberProvider
{
    long MemberId { get; }
}

public class FixedMemberProvider : IMemberProvider
{
    public MemberProvider(long memberId)
    {
        MemberId = memberId;
    }

    public long MemberId { get; set; }
}

I have registered like this,

 builder.RegisterType<FixedMemberProvider>().As<IMemberProvider>()
     .InstancePerLifetimeScope();

In Middleware or in anyplace I resolve like this,

using var messageScope = _lifetimeScope.BeginLifetimeScope();

if (!string.IsNullOrEmpty(message.MemberId))
    messageScope.Resolve<IMemberProvider>(
        new TypedParameter(typeof(string), message.MemberId));

So within the scope I can access GetMemberId() method. Can anyone help to get this done by Microsoft DI.

Upvotes: 0

Views: 1105

Answers (2)

Travis Illig
Travis Illig

Reputation: 23924

Basic Microsoft.Extensions.DependencyInjection does not support parameters during resolution. That container is intended to be a lowest-common-denominator conforming container that could be backed by any DI container, from Autofac to Simple Injector. If you want to use additional features, that's specifically why you can back it with a richer container. If you need Autofac features... use Autofac.

Upvotes: 4

Qing Guo
Qing Guo

Reputation: 9112

If you are trying to use dependency injection in ASP.NET Core, you can read this.

Below is a demo about Constructor Method Injection,you can refer to it.

ICounter.cs:

public interface ICounter
    {
        int Get();
    }

Counter.cs:

public class Counter : ICounter
    {
        private int _count;
        public int Get()
        {
            return _count++;
        }
    }

Add below to Program.cs:

builder.Services.AddScoped(typeof(ICounter), typeof(Counter));

Controller.cs:

public class HomeController : Controller
    {

        private ICounter _counter;
        public  HomeController(ICounter counter)
        {
            _counter = counter;
        }
        public IActionResult Index()
        {
            int count = _counter.Get();
            ViewBag.Count = count;  
            return View();
        }       
    }

Using Scoped objects in middleware, you can inject the required objects in the InvokeAsync method. TestCounterMiddleware.cs:

public class TestCounterMiddleware
    {
        private RequestDelegate _next;
        public  TestCounterMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context,ICounter counter)
        {
            int count = counter.Get();
            await _next(context);
        }
    }

Add below to Program.cs:

app.UseMiddleware<TestCounterMiddleware>();

Result:

enter image description here

Upvotes: 0

Related Questions