你能在objective-c中完成某种形式的依赖注入吗?

时间:2011-01-09 14:30:18

标签: objective-c dependency-injection

目前我在需要时直接对另一个对象进行硬编码,我希望能够通过init方法接受它(我假设?)。在下面的代码中,我在viewDidLoad方法中创建了一个新的HatService,出于可测试性/耦合的原因,我不想这样做。

- (void)viewDidLoad
{
    [super viewDidLoad];
    HatService* hatService = [[HatService alloc] init];
    [hatService getHatById:self];
}

第一个问题 - 如何在Objective-c中完成? 第二个问题 - 我应该担心这个问题还是做到这一点?

更新

以下是我的开始,但我似乎从未在运行时遇到第一个init方法。我在界面中都声明了 - 我错过的任何其他东西都允许我覆盖这个init方法并注入服务依赖项?

注意 - 当我自己创建对象时,我可以手动点击这个但是当appDeleage完成工作时我没有看到它(如果app委托创建这个对象而不调用我的init方法?)

-(id)initWithHatService:(HatService *)service
{
  if (self = [super init])
  {
    [self setService:service];
  }
  return self;
}

-(id)init
{
  HatService* hatService = [[HatService alloc] init];
  return [self initWithHatService:hatService];
}

3 个答案:

答案 0 :(得分:6)

UIViewController的指定初始值设定项为- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle。如果您希望从nib文件中正确实例化视图控制器,则需要覆盖此方法,如果这是您正在尝试执行的操作。没有看到更多的代码,就无法分辨,但这种方法肯定会被称为某个地方。

其次,您需要重新编写-init方法,如下所示:

- (id)init {
    return [self initWithHatService:nil];
}

每个init方法都应调用指定的初始化程序。

最后,当您处理视图控制器时,人们通常不会在init方法中传递属性。实例化新控制器,然后将其传递给您喜欢的任何服务属性。

MyViewController *newContrlr = [[MyViewController alloc] initWithNibName:nil bundle:nil];
newContrlr.hatService = [[[HatService alloc] init] autorelease];

答案 1 :(得分:1)

如果您正在询问如何将对象传递给另一个对象的init方法,只需将您的init方法声明为接受一个或多个参数即可。即- (id) initWithHatService:(HatService *)serv; init方法除了objective-c中的约定之外没有任何特殊之处。

无关:您的-getHatById:方法很奇怪。那个内存管理语义是什么?在Cocoa程序中,get-prefixed方法非常罕见。

答案 2 :(得分:0)

在Objective-C中实现依赖注入设计模式非常容易。您可以通过创建定义单个协作者的“应用程序集”类来手动完成。

或者,您可以使用框架来提供帮助。我最近创建了一个名为Typhoon的DI容器:http://www.typhoonframework.org