3

我的服务使用一个实用程序类,并且该实用程序类有几个公共属性。我需要打电话来确保设置这些公共属性吗?

该服务使用 ASP.NET 主机。在 Global.ASAX 内部,我声明了一个新的 AppHostBase:

public class MyServiceHost : AppHostBase
{
    public MyServiceHost() : base("My Service Host", typeof(ServiceLibrary).Assembly) {}

    public override void Configure(Funq.Container container)
    {
        container.Register<IDbConnectionFactory>(dbConFactory);

        container.RegisterAutoWired<UtilityLibrary>();
        container.RegisterAutoWired<RepositoryLibrary>();
    }
}

在我的存储库和实用程序库中都有一个主类。这可能类接收容器并注册更具体的实用程序和存储库:

public class UtilityLibrary
{
    public UtilityLibrary(Funq.Container container)
    {
        container.RegisterAutoWired<WidgetAActions>();
        container.RegisterAutoWired<WidgetBActions>();
    }
}

在下面的示例中,在 RepositoryLibrary 类的构造函数中设置了 WidgetARepository。包含 WidgetARepository 的 RepositoryLibrary 类在 AppHost 的Configure方法中提供给 Container(上面的第一个片段)。即便如此,WidgetARepository(如下)从未设置:

public class WidgetAActions
{
    public WidgetARepository WidgetARepository { get; set; }

    public WidgetA Get(string id)
    {
        var item = this.WidgetARepository.Get(id);
        if (item == null) { return null; }

        // Do something else

        return item;
    }
}

我必须手动调用Resolve()吗?这样做似乎会破坏注入的目的。

4

1 回答 1

3

如果您想在 ServiceStack 服务之外使用 Funq Container Autowire IoC,那么您需要调用Container.AutoWire自己让容器注入相关的依赖项。此调用是在 ServiceStack 请求管道中的幕后进行的。

对于 ServiceStack v4:

HostContext.Container.AutoWire(objectToPopulate);

对于 ServiceStack v3:

AppHostBase.Instance.Container.AutoWire(objectToPopulate);

我通常会将此调用添加到要填充注入的对象的构造函数中。所以在你的情况下:

public class WidgetAActions
{
    public WidgetARepository WidgetARepository { get; set; }

    public WidgetAActions()
    {
        // (Substitute with v3 usage if required.)
        HostContext.Container.AutoWire(this);
    }

    ...
}

希望这可以帮助。


编辑:您是否考虑过让容器将相应的存储库注入WidgetAActions的构造函数?

container.RegisterAutoWired<WidgetAActions>(c => new WidgetAActions(c.Resolve<WidgetARepository>()));

public class WidgetAActions
{
    public WidgetARepository WidgetARepository { get; private set; }

    public WidgetAActions(WidgetARepository repository)
    {
        WidgetARepository = repository;
    }

    ...
}

编辑:或者您可以解析并将对象的公共属性设置为存储库,然后您不必有构造函数:

container.RegisterAutoWired<WidgetAActions>(c => 
    new WidgetAActions { WidgetARepository = c.Resolve<WidgetARepository>() }
);

public class WidgetAActions
{
    public WidgetARepository WidgetARepository { get; set; }

    ...
}

或者您可以在解决时调用 autowire WidgetAActions

container.RegisterAutoWired<WidgetAActions>(c => {
    var actions = new WidgetAActions();
    container.AutoWire(actions); // All dependencies injected
    return actions;
});

public class WidgetAActions
{
    public WidgetARepository WidgetARepository { get; set; }

    ...
}
于 2014-02-16T19:58:49.593 回答