简体   繁体   中英

ASP.NET Core how to pass parameter in service builder

I've read a very useful article from Michael McKenna blog about creating a multi-tenant application but I've a couple of issues. The first one in the TenantMiddleware class as Constants.HttpContextTenantKey is undefined, it's likely due to some missing code, I've set a constant string in the meantime.

The main issue is that I'd like to pass the tenants array in the InMemoryTenantStore class when I call the service at startup. I've modified the InMemoryTenantStore class

 public class InMemoryTenantStore : ITenantStore<Tenant>
{
    private readonly Tenant[] _tenants;
    public InMemoryTenantStore(Tenant[] tenants)
    {
        _tenants = tenants;
    }

but I don't have idea how to pass the array in the calling service. I guess I need to tweak this code

 public TenantBuilder<T> WithStore<V>(ServiceLifetime lifetime = ServiceLifetime.Transient) where V : class, ITenantStore<T>
    {
        _services.Add(ServiceDescriptor.Describe(typeof(ITenantStore<T>), typeof(V), lifetime));
        return this;
    }

But I can't find any example about this and unfortunately I can't reach the author blog.

For creating object instances through ServiceDescriptor with parameters you must to provide implementation factory to it, not just implementation type.

You can do this two ways:

  1. Just create instance directly before WithStore method.
  2. Create implementation factory for build TenantBuilder (using lambda or separate method)
// Creating instance outside
public TenantBuilder<T> WithStore<V>(V store, ServiceLifetime lifetime = ServiceLifetime.Transient) where V : class, ITenantStore<T>
{
    _services.Add(ServiceDescriptor.Describe(typeof(ITenantStore<T>), provider => store, lifetime));
    return this;
}

// Implementation factory
public TenantBuilder<T> WithStore<V>(Func<IServiceProvider, V> implementationFactory, ServiceLifetime lifetime = ServiceLifetime.Transient) where V : class, ITenantStore<T>
{
    _services.Add(ServiceDescriptor.Describe(typeof(ITenantStore<T>), implementationFactory, lifetime));
    return this;
}

this is what I did

public class Constants
    {
        public static Dictionary<string, object> HttpContextTenantKey { get; private set; } = new Dictionary<string, object>();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM