Unity 应用程序块,如何将参数传递给注入工厂?

8
这是我现在拥有的内容。
  Container.RegisterType<IUserManager, UserManagerMock>();
  Container.RegisterType<IUser, UserMock>(
                new InjectionFactory(
                    (c) => c.Resolve<IUserManager>().GetUser("John")));

并获取它

Container.Resolve<IProfile>();

我想将名称作为参数传递给工厂,以便我能够通过名称解析用户对象; 类似这样:
 Container.Resolve<IProfile>("Jonh");

我该如何更改此案例的类型注册?

就我个人而言,我不会尝试通过服务定位来检索IUser/IProfile。只需通过服务定位检索IUserManager,然后在您的代码中调用GetUser("John")即可。 - John Bledsoe
我同意John的观点。如果可能的话,尽量使用依赖注入而不是服务定位。这样可以使您的代码免于对容器的调用,并且在应用程序中只有一个(或最多几个)地方调用容器。 - Steven
2个回答

7

尽管大多数DI框架都有高级功能来完成这些类型的注册,但我个人更喜欢改变应用程序的设计来解决这样的问题。这使得我的DI配置简单,并使代码更易于理解。特别是对于依赖于某些上下文(线程、请求等)或必须明确管理生命周期的对象的创建,我喜欢定义工厂。工厂使这些事情更加明确。

在您的情况下,您想要为某个用户获取配置文件。这通常是您希望拥有一个工厂的内容。以下是此类内容的示例:

// Definition
public interface IProfileFactory
{
    IProfile CreateProfileForUser(string username);
}

// Usage
var profile = Container.Resolve<IProfileFactory>()
    .CreateProfileForUser("John");

// Registration
Container.RegisterType<IProfileFactory, ProfileFactory>();

// Mock implementation
public class ProfileFactory : IProfileFactory
{
    public IProfile CreateProfileForUser(string username)
    {
        IUser user = Container.Resolve<IUserManager>()
            .GetUser(username);

        return new UserProfile(user);
    }
}

我希望这有所帮助。

我认为这类示例(我们调用容器)让我感到困惑的是,您直接调用了容器。难道不应该是相反的吗?我不会引用那句不太好的谚语,但您知道我的意思... - brumScouse
Steven.. 非常感激,简单、友好、有效.. 对我来说它就像魔法一样运作。 - alhpe

6

Resolve方法允许传递ResolverOverride参数。ResolverOverride的子类型是ParameterOverride,可用于将参数传递给已解析的构造函数。

您可以这样做(参数为Name,传递的值为John):

Container.Resolve<IProfile>(new ParameterOverride("Name", "John"));

1
真的,但是你不会将这些参数传递到工厂方法中。 - haim770

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接