使用Simple Injector

时间:2018-05-18 21:20:45

标签: c# .net dependency-injection ioc-container simple-injector

我有界面IConnector。并且有一些实现,比如SomeConnector。我的用例看起来像:

public class Worker : IWorker
{
    public Worker(IConnector dataConnector, IConnector transactionConnector) {}
}

public class SomeConnector : IConnector
{
    public SomeConnector(IConnectorContext connectorContext) {}
}

Worker构造函数中,我需要有两个IConnector实例。不仅仅是两个实例,而是两个特定实例,使用它们自己的上下文创建。我该如何进行此注册?

UPDATE1

添加ConnectorContext实施

public class SomeConnectorContext : IConnectorContext
{
    public List<string> Types { get; }
    public int DataTimeoutSeconds { get; }
    public string Key { get; }
    public string ConnectorName { get; }

    public SomeConnectorContext(
        List<string> types, int dataTimeoutSeconds, string key, string connectorName)
    {
        Types = types;
        DataTimeoutSeconds = dataTimeoutSeconds;
        Key = key;
        ConnectorName = connectorName;
    }
}

UPDATE2

实际上我需要基于配置的某种条件注册。例如:

switch (workerType)
{
    // the following code is obviously incorrect, because I
    // don't know how make registrations properly in this case.
    case "worker1":
        //create context for dataConnector based on config.
        Container.Register<IConnectorContext>(new SomeConnectorContext(...));
        //this is dataConnector. and should use dataConnector context.
        Container.Register<IConnector, SomeConnector>();

        //create context for transactionConnector based on config.
        Container.Register<IConnectorContext>(new SomeConnectorContext(...));
        //this is transactionConnector. and should use transactionConnector context.
        Container.Register<IConnector, SomeConnector>();

        Container.Register<IWorker, Worker1>();
        break;

    //in the following case Worker2 needs only one Connector
    case "worker2":
        //create context for allPurposeConnector based on config.
        Container.Register<IConnectorContext>(new SomeConnectorContext(...));
        //this is allPurposeConnector. and should use allPurposeConnector context.
        Container.Register<IConnector, SomeConnector>();

        Container.Register<IWorker, Worker2>();
        break;
}

UPDATE3 添加workerType赋值示例。

workerType是配置值。例如,它可以像这样设置: workerType = Properties.Settings.Default.WorkerType;

1 个答案:

答案 0 :(得分:0)

我看到两个选项。

您可以使用lambda手动连接依赖项。这意味着您只需注册switch (workerType) { case "worker1": var context1 = new SomeConnectorContext(...); var context2 = new SomeConnectorContext(...); Container.Register<IWorker>(() => Worker1( new SomeConnector(context1), new SomeConnector(context2))); break; case "worker2": var context1 = new SomeConnectorContext(...); Container.Register<IWorker>(() => Worker1( new SomeConnector(context1))); break; } 并手动构建它及其依赖项。这会禁用自动连线,但会产生相当简单的代码,如下例所示:

SomeConnector

您的第二个选择是将SomeConnector注册为有条件注册。这允许您进行两个IWorker注册,并将它们链接到相应的构造函数参数。这允许switch (workerType) { case "worker1": var context1 = new SomeConnectorContext(...); Container.RegisterConditional<SomeConnector>( Lifestyle.Transient.CreateRegistration( () => new SomeConnector(context1), container), c => c.Consumer.Target.Name == "dataConnector"); var context2 = new SomeConnectorContext(...); Container.RegisterConditional<SomeConnector>( Lifestyle.Transient.CreateRegistration( () => new SomeConnector(context2), container), c => c.Consumer.Target.Name == "transactionConnector"); Container.Register<IWorker, Worker1>(); break; case "worker2": Container.Register<IConnectorContext>(new SomeConnectorContext(...)); Container.Register<IConnector, SomeConnector>(); Container.Register<IWorker, Worker2>(); break; } 自动连接,但会导致更复杂的注册,如下所示:

 app.use('/client', bodyParser.json() ,  
  (req, res,next) => {
    const context = { pool , apiKey:req.query.key , bidules };
    if (server.isAuthorized(context.apiKey)) {
      return graphqlExpress({
        schema: schema,
        context: context,
        tracing: true,
        cacheControl: {
          defaultMaxAge: 30,
        }
      }) (req,res,next); 
    }
    else {
      res.setHeader('Content-Type', 'application/json');
      res.status(403)
      .send (JSON.stringify({
        errors:[ {message: "api key is unauthorized"} ]
      })); 
    }
  }
);

// endpoint for browser graphIQL
app.use('/graphql',  graphiqlExpress({ 
  endpointURL: '/client' 
}));


app.use("/schema", (req, res) => {
  res.set("Content-Type", "text/plain");
  res.send(printSchema(schema));
});