Can't get value of Ninject ConstructorArgument (passed in as parameter to kernel.Get)

前端 未结 2 1708
广开言路
广开言路 2021-01-26 10:50

Having trouble getting the value of a ConstructorArgument parameter passed to kernel.Get(). I want to use the parameter\'s value to determine which of two string values will

相关标签:
2条回答
  • 2021-01-26 11:07

    Edit: After your comments and edits, I've reformulated the answer. The suggestion below is just one way to go about this. I'm implementing a Provider<ObjectContextFactory> that will inspect the parameter sent to the request when using kernel.Get<ObjectContextFactory>(). This parameter has nothing to do with constructor, it is only used as a "context variable" so you can decide what to do with it.

    Here is the code:

    public class ObjectContextFactory
    {
        private readonly string _idNum;
        private readonly IResolutionRoot _container;
    
        public ObjectContextFactory(IResolutionRoot container, string idNum)
        {
            _container = container;
            _idNum = idNum;
        }
    
        public ObjectContext CreateObjectContext()
        {
            //Use _idNum here as you wish, here is a sample implementation
            ConstructorArgument constructorArgument;
            if (_idNum.Substring(0,1) == "2")
            {
                constructorArgument = new ConstructorArgument("connectionString", "your conn string 1");
            }
            else
            {
                constructorArgument = new ConstructorArgument("connectionString", "your conn string 2");
            }
    
            return _container.Get<ObjectContext>(constructorArgument);
        }
    }
    
    public class ObjectContextFactoryProvider : Provider<ObjectContextFactory>
    {
        protected override ObjectContextFactory CreateInstance(IContext context)
        {
            var idNum = context.Parameters.FirstOrDefault(p => p.Name == "idNum");
            var idNumValue = idNum.GetValue(context, null) as string;
    
            var factory = new ObjectContextFactory(context.Kernel, idNumValue);
            return factory;
        }
    }
    

    And the bindings:

    public override void Load()
    {
        Bind<DBProviderBase>().To<DBProviderB>();
        Bind<ObjectContextFactory>().ToProvider<ObjectContextFactoryProvider>();
    }
    

    When retrieving the factory:

    var factory = kernel.Get<ObjectContextFactory>(new Parameter("idNum", "1", true));
    

    Another way to achieve this would be via Named Bindings. Just do a kind of translator from your idNum to a string (or use it directly) and call it when getting an instance.

    0 讨论(0)
  • 2021-01-26 11:34

    I needed to use ToMethod() to get access to the appropriate context.

    Bind<DBProviderBase>().ToMethod(
        ctx => {
            var idNum = ctx.Parameters.First(p => p.Name == "idNum")
                .GetValue(ctx, null) as string
            ;
    
            if (idNum == 2) {
                return new DBProviderB(new EF_DBEntities(
                    ConfigurationManager.ConnectionStrings["EF_DB_b_conn1"]
                .ToString()));
            } else {
                return new DBProviderB(new EF_DBEntities(
                    ConfigurationManager.ConnectionStrings["EF_DB_b_conn2"]
                .ToString()));
            }
        };
    );
    
    //later...
    var db = kernel.Get<DBProviderBase>(
        new Ninject.Parameters.Parameter("idNum", idNum, true)
    );
    
    0 讨论(0)
提交回复
热议问题