【问题标题】:Injecting Runtime Objects Using Lamar使用 Lamar 注入运行时对象
【发布时间】:2020-12-29 16:11:50
【问题描述】:

我正在尝试为我维护的框架为 Lamar 构建一个包。 为了说明我引用 StructureMap 的意思,能够将运行时对象与 Service 抽象混合的相关方法是(将容器传递给该工厂类的构造函数):

public IPresenter Create(Type presenterType, Type viewType, IView viewInstance)
{
    container.Configure(x => x.For(presenterType)
        .Use(presenterType)
        .Named(presenterType.Name)
        );

    var args = new ExplicitArguments();
    args.Set("view");
    args.SetArg("view", viewInstance);

    return (IPresenter)container.GetInstance(presenterType, args);
}

我意识到 Lamar 没有实现 ExplicitArguments(很公平)。

我玩过 Injectable 功能,但无法让它发挥作用:

public IPresenter Create(Type presenterType, Type viewType, IView viewInstance)
{
    var c = _container.GetNestedContainer();
    c.Inject(viewInstance);

    // return c.GetInstance(presenterType, presenterType.Name.ToString()) as IPresenter; // BOOM!!!

    return _container.GetInstance(presenterType) as IPresenter; // BOOM!!!
}

在拉马尔有其他方法吗?

这是我的注册码:

IContainer container = new Container(c =>
{
    c.AddTransient<ISomeService, SomeService>();
    c.Injectable<IMainView>();
    c.AddTransient<MainPresenter>();
});    

我创建了一个示例项目,它重新创建了可以是downloaded here 的问题。它使用 .NET 5

在该项目中,如果您在 MainPresenter 类中设置断点,您将看到 IView 参数为 null 并且 OrdersService 确实解析。

我还需要传入作为主要表单的具体对象(作为IView)。

干杯

【问题讨论】:

  • 我似乎已经用上面的代码来工作了。我犯的错误是我将注射剂注册为IView,而不是从IView继承的接口,即IMainView。所以,c.Injectable&lt;IMainView&gt;();
  • 我说得太早了。这不起作用。解析 IPresenter 时,IView 为空。我已经用我正在使用的注册码更新了答案。
  • edit您的问题包含您拥有的完整源代码作为minimal reproducible example,其他人可以编译和测试。另请参阅:What Do You Mean “It Doesn't Work”?。 “BOOM !!!”到底是什么意思?你有例外吗?
  • @Progman 我添加了一个指向 zip 文件的链接,其中包含一个重新创建问题的示例项目。我最初遇到了一个例外,当我发布问题时忘记删除对 BOOM 的引用。谢谢。
  • 不要在外部站点上添加源代码,将 MCVE 添加到问题本身。

标签: c# lamar


【解决方案1】:

LamarPresenterFactory.Create方法viewInstance参数有问题

public IPresenter Create(Type presenterType, Type viewType, IView viewInstance)
{
}

我注意到它应该是IMainView 类型,如下所示

public IPresenter Create(Type presenterType, Type viewType, IMainView viewInstance)
{
    var nestedContainer = _container.GetNestedContainer();
    nestedContainer.Inject(viewInstance);

    return nestedContainer.GetInstance(presenterType) as IPresenter;
}

nestedContainer.Inject(viewInstance) 参数数据类型要求 viewInstancec.Injectable&lt;IMainView&gt;(); 使用的类型相同

我收到OrdersService.GetOrders 异常,因为没有可用的orders.zip 文件

【讨论】:

  • IMainView 继承 IView。不幸的是,该参数必须是 IView,否则我们必须为每个演示者编写一个 Create 方法。 Create 方法来自一个通用接口,所有支持的 DI 容器都实现了(目前只有 2 个)。我最初尝试注册 c.Injectable&lt;IView&gt;(); ,但在调用 GetInstance 时抛出异常。
  • @onefoots 看起来很奇怪,因为您声明要注入 IMainView,但又不想注入 IView 实例。这可能导致Create 将获得IView 参数实例(不是IMainView),您认为容器如何将IView 注入presenterType 而不是IMainView?您可以将容器配置为c.Injectable&lt;IView&gt;();,这允许将IView 实例注入presenterType 构造函数。
  • 看起来 Lamar 还没有我所追求的能力。如果您查看我帖子的顶部,则可以使用 StructureMap。 ExplicitArguments 在此处配置,然后在 Create 方法中进行配置。我还用SimpleInjectorAutofac 实现了它,它们都有不同但有效的方法。这没什么大不了的。我会尽可能多地支持 IOC 框架。如果 Lamar 将来支持它,我会添加支持。如果现在可以,并且有人可以告诉我如何,同样。拉马尔看起来很棒,所以如果可以的话,我一定会支持它。干杯。
猜你喜欢
  • 2012-08-05
  • 1970-01-01
  • 2013-06-14
  • 2014-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-17
相关资源
最近更新 更多