简体   繁体   中英

Is it possible to inject an NSManagedObject instance using the Typhoon framework?

I would like to inject NSManagedObject subclasses with the Typhoon framework. I have not seen an example of that, but I am thinking it might be possible.

I am using MO Generator, and have a superclass in between the NSManagedObject and the ultimate child class.It's in this common abstract base class where I would want to inject if that makes any difference.

Has anyone had any success with this?

Any advice would be appreciated. Please let me know if there is more information that I can provide.

Setting up Core Data with Typhoon:

Firstly, if you want to set up Core Data with Typhoon, so that you could inject, for example, data sources into your view controllers, there is a Typhoon+CoreData+RAC sample application that was kindly posted by Ryoichi Izumita . It shows:

  • Typhoon's UIStoryboard integration
  • Core Data
  • Reactive Cocoa

In this sample . . .

The top-level assembly is CDRApplicationAssembly

  • The AppDelegate is injected at startup with some Core Data components. This allows the app delegate to save the context when the application is terminated.
  • The's a CDRViewController , which is declared on the main story board. Because we've boot-strapped Typhoon from the app's plist file all storyboards will be an instance of TyphoonStoryboard. These work just like regular storyboards with the added benefit that dependencies are injected according to the rules outline in our assembly. This controller is injected with a Core Data datasource.
  • Ryoichi-san created a category on NSManagedObjectContext , making it easier to set up with DI and integrate Reactive Cocoa.

Core Data Assembly:

The main assembly refers to a helper assembly - CDRCoreDataComponents , which is responsible for setting up core data. Some of the values in this file are loaded from a configuration file , which makes it easy to set up eg production vs test environments.

Now to address your question specifically. . .


Injecting model classes themselves:

Often persistent domain objects tend to have properties without methods, and many argue that this should not be the case (its called by Martin Fowler and others 'the anemic domain object anti-pattern ). They argue that in a correct object-oriented design, model objects will have behaviors as well as properties, and that the ideal place for behaviors is close to the data that they represent.

The problem is that:

  • In order for domain objects to have behaviors, they must often rely on collaborators.
  • But of course, if the objects seek out their own dependencies, we'd have another anti-pattern. DI is required.


The 'hook-point' approach (supported by Typhoon):

We can instruct Typhoon to inject a pre-obtained instance as follows:

Knight* knight = ... //Loaded from persistent storage
[componentFactory inject:knight]; //Matches by type
[componentFactory inject:knight withDefinition:@selector(selectorInAssembly)];

This is the 'hook-point' approach. After obtaining an instance we tell Typhoon to inject it. First we inject the TyphoonComponentFactory itself into our Data Access Object, network client or whatever will be emitting the object. As the last step, we tell Typhoon to inject our model, according to the recipe defined in the assembly. Et voila!


A custom core data integration (not supported by Typhoon):

Instead of using this 'hook-point' approach, perhaps we could provide a tighter integration with Core Data (as we've done with UIStoryBoard), so that the above step is not necessary? This is not currently supported by Typhoon.


Using AOP to Inject Domain Objects: (not supported by Typhoon)

In fact, besides a specific solution for Core Data, there's another approach to inject any domain object using "AOP". By that we mean intercepting and instrumenting all of a domain object's init methods to subsequently load dependencies according to the rules in an Assembly. This is how the @Configurable annotation in Spring (a popular DI+AOP framework for Java) works. The problem is finding a suitable way to associate the model object with a TyphoonComponentFactory , without this being too invasive (ie a singleton). There's some drawbacks to saying "every instance of this Product, Car and Holiday are associated with this assembly", which is why we've favored the "hook-point' approach so far.

Your Feedback:

If you're happy with the hook-point approach then great. If you're interested in either a specific core data integration or the "AOP" solution described above, then we'd enjoy exploring it with you. There's been a few discussions already.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM