2014-02-16 18 views
2

我的服务使用工具类,该工具类有几个公共属性。有什么特别的我需要调用以确保这些公共属性的设置?ServiceStack的Funq.Container没有新的属性

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

在下面的例子,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()?这似乎是通过这样做会打败注射的目的。

回答

2

如果您希望在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

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

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

    ... 
} 
+0

从技术上讲,这些仍在服务范围内。 UtilityLibrary类引用RepositoryLibrary类。两者都在服务的AppHost中注册到容器中。唯一可能有点不同寻常的因素是(不明白为什么会这样),UtilityLibrary和RepositoryLibrary都有构造函数,它们将子类添加到Container中。在这种情况下,WidgetARepository将是RepositoryLibrary的子类。 –

+1

@ RyanD'Baisse我可以看到,你肯定是添加你的'UtilityLibrary','RepositoryLibrary','WidgetAActions'和'WidgetBActions'的容器,但'Container.AutoWire'不会递归运行。所以当ServiceStack服务运行时,它会自动装载你的'WidgetAActions',因为你将它包含在你的服务中。但它无法在'WidgetAActions'中看到依赖关系。你必须按照我的建议调用'AutoWire'。或者如果只有一个依赖项,则使用'HostContext.Container.Resolve ()'。 – Scott

+0

@ RyanD'Baisse当容器解析WidgetAActions时,我添加了一个替代方法,它将存储库传递给WidgetAActions的构造函数。 – Scott