JSONAPIdotNET / JSONAPI.NET

MIT License
102 stars 23 forks source link

polymorphism #73

Open csantero opened 9 years ago

csantero commented 9 years ago

In order to support json-api polymorphism, we need a new method on IModelManager called GetTypeForJsonKey, which would be the inverse of GetJsonKeyForType. In order to make this work, we will need some sort of type registry. @SphtKr any ideas?

SphtKr commented 9 years ago

Yes, the default ModelManager already keeps one, though it's protected (intended to be usable by subclasses but I'm not sure how well that works ATM). We could formalize that cache I imagine.

Right now the MO of ModelManager is to add things to its cache as it encounters them, but that could easily be changed to allow a user to pre-register a model object to speed up the process.

I'd love for the system to work without requiring users to preregister their model types, but if we have to we have to. It comes to mind that we should add utility methods to register everything in a namespace and something in the EF Library to register everything in a DbContext.

Point being, I think IModelManager should be where users register models. And, if we want them to be able to do so anywhere else besides the JsonApiFormatter constructor, we have to have a way to get a hold of the IModelManager instance providing the registry. This is going to be needed anyway, because MetadataManager needs to be able to find the IModelManager instance, and users need to be able to reach the MetadataManager from within their ApiControllers...so constructor injection alone won't cut it. Whether or not we use Autofac or DependencyResolver or whatever for this is TBD, but again brings us back to the service locator problem.

I think formalizing a registry is going to be good, because then it'll be possible to do the Ember Data model generator thing I've mentioned before. We'll probably find other use cases as well.

Make sense? Thoughts?

csantero commented 9 years ago

Sounds like we're on the same page pretty much. If we merge #62 then I think we can let users register their models with the fluent API, and then there is no need to expose IModelManager to them. We might need some other interface to facilitate registration. Something like:

public interface IResourceTypeRegistrationProvider
{
    Type[] RegisterTypes();
}
public class MyResourceTypeRegistrationProvider : IResourceTypeRegistrationProvider
{
    ...
}
new JsonApiConfiguration()
    .RegisterTypesUsing(new MyResourceTypeRegistrationProvider());

Regarding the MetadataManager, I think we can avoid needing to steal the DependencyResolver by using a custom model binder and then passing an IMetadataManager instance to action methods. So the PUT method signature would change to:

Task<IList<T>> Put(string id, IList<T> putObjs, IMetadataManager metadata);

I'm not entirely sure that this is possible, but I'll look into it when I get a chance. If it works, then we can finally get rid of the singleton MetadataManager and make it a constructor param for JsonApiFormatter.