我的服务使用实用程序类,该实用程序类有几个公共属性。我需要调用哪些特殊功能来确保设置这些公共属性吗?
该服务使用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()
吗?这似乎会通过这样做来打败注射的目的。
答案 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; }
...
}