首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将接口参数传递给Spring4D?

如何将接口参数传递给Spring4D?
EN

Stack Overflow用户
提问于 2016-06-27 20:51:53
回答 2查看 649关注 0票数 1

我有下面的例子。

是否有更简单的方法来传递已经为Container注册的接口变量来解决它?

或者,还有其他方法来使用这个特性吗?

,那是我的接口,

代码语言:javascript
复制
    IString = interface
      function Value: string;  
    end;  

    IUser = interface
      function Name: IString;
    end;

    ILogin = interface
      function User: IUser;
      function Password: IString;
    end;

类实现

代码语言:javascript
复制
    TString = class(TInterfacedObject, IString)
    private
      FValue: String;
    public
      constructor Create(const AValue: String);
      function Value: String;
    end;

    TUser = class(TInterfacedObject, IUser)
    private
      FName: IString;
    public
      constructor Create(const AName: IString);
      function Name: IString;
    end;

    TLogin = class(TInterfacedObject, ILogin)
    private
      FUser: IUser;
      FPassword: IString;
    public
      constructor Create(const AUser: IUser; const APassword: IString);
      function User: IUser;
      function Password: IString;
    end;

容器上的注册

代码语言:javascript
复制
    GlobalContainer.RegisterType<TString>.Implements<IString>;
    GlobalContainer.RegisterType<TUser>.Implements<IUser>;
    GlobalContainer.RegisterType<TLogin>.Implements<ILogin>;

调用

因此,当必须创建这些接口(我以这种方式调用)时,这些嵌套参数使代码变得复杂,需要阅读(并查看)。

代码语言:javascript
复制
    GlobalContainer.Resolve<ILogin>([
      TValue.From(
        GlobalContainer.Resolve<IUser>([
          TValue.From(
            GlobalContainer.Resolve<IString>(['UserName'])
          )
        ])
      ),
      TValue.From(
        GlobalContainer.Resolve<IString>(['SuperSecretPassword'])
      )
    ]);
EN

回答 2

Stack Overflow用户

发布于 2016-06-28 09:10:29

首先,这闻起来像服务定位器反模式 --你应该使用工厂。

当前构造需要有关对象图的知识,并将两个不同的值传递给相同的类型。一家工厂很适合做的事。

因此,您可以为您的情况注册一个工厂,而不是仅仅用使用者代码中的一个解析调用替换一个ctor调用(您应该尽可能避免这样的事情):

代码语言:javascript
复制
type
  ILoginFactory = interface
    [some guid]
    function CreateLogin(const userName, password: string): ILogin;
  end;

  TLoginFactory = class(TInterfacedObject, ILoginFactory)
    function CreateLogin(const username, password: string): ILogin;
  end;

  function TLoginFactory.CreateLogin(const username, password: string): ILogin;
  begin
    // can also inject the container to the factory and use resolve here - 
    // but doing it the pure DI way for now because the graph to create is simple
    Result := TLogin.Create(
      TUser.Create(
        TString.Create(username)),
      TString.Create(password));
  end;

然后,应该将这个ILoginFactory注入到当前具有GlobalContainer.Resolve调用的类中。这也有助于提升到复合根

票数 3
EN

Stack Overflow用户

发布于 2016-06-28 14:38:13

我找到了一个让电话更容易处理的方法。

也许我做得不对。但这会让电话变得更简单。

我创建了一个助手类

代码语言:javascript
复制
    TContainerHelper = class helper for TContainer
    public
      ResolveAsTValue<T>: TValue; overload;
      ResolveAsTValue<T>(name: string): TValue; overload;
      ResolveAsTValue<T>(arguments: array of TValue): TValue; overload;
      ResolveAsTValue<T>(name: string;arguments: array of TValue): TValue; overload; 
    end;

现在,当我需要解析依赖于另一个接口的接口时,我只是:

代码语言:javascript
复制
    GlobalContainer.Resolve<ILogin>([
      GlobalContainer.ResolveAsTValue<IUser>([
        GlobalContainer.ResolveAsTValue<IString>(['UserName'])
      ]),
      GlobalContainer.ResolveAsTValue<IString>(['SuperSecretPassword'])
    ]);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38063018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档