ServiceStack的Funq.Container不是Newing-Up属性

时间:2014-02-16 18:46:09

标签: servicestack funq

我的服务使用实用程序类,该实用程序类有几个公共属性。我需要调用哪些特殊功能来确保设置这些公共属性吗?

该服务使用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>();
    }
}

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

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

在下面的示例中,WidgetARepository是在RepositoryLibrary类的构造函数中设置的。包含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()吗?这似乎会通过这样做来打败注射的目的。

1 个答案:

答案 0 :(得分:3)

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

对于ServiceStack v4:

HostContext.Container.AutoWire(objectToPopulate);

对于ServiceStack v3:

AppHostBase.Instance.Container.AutoWire(objectToPopulate);

我通常会将此调用添加到我想用注入填充的对象的construtor方法中。所以在你的情况下:

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; }

    ...
}

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

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

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

    ...
}