In bug [#1463](https://entityframework.codeplex.com/workitem/1463) I have described that it would be nice to have a way to construct a mutable EdmFunction using public surface. This happens to be just one case of a more general issue affecting most of the metadata API. The current situation is a side effect of how we have worked on metadata mutability/constructability in EF6.
Fundamentally all the work we did was driven by two different "customers" that had different requirements:
* __Designer:__ The metadata usage patterns of the EF designer did not really need mutability but just public constructability (in fact, mutability for the designer is dangerous because unlike EF code first the designer does not define an entry point for making the whole model immutable by calling the SetReadOnly method in cascade). Also in some cases the designer needs to deal with unfinished models in which the XML for a specific item exists in the EDMX but is insufficient to construct an instance of the valid item in memory. Give those two requirements we went down the path of adding a bunch of 'Create' factory methods on metadata types that return already finished (i.e. locked) instances
* __Code First:__ The metadata usage patterns of EF code first generally use mutability but this mutability is not necessarily public because all the built-in conventions and discrete code first logic obviously has access to internals. Code First does define an entry point in which a model can transition to an immutable state, that is used when a DbModel is compiled into a DbCompiledModel, therefor it is safe in general in the Code First pipeline to leave objects as mutable.
We did not take the chance in EF6 to reconcile the requirements of public constructability and mutability, therefore we ended up with:
* Factory methods that at least in the majority of cases return locked objects
* A mix of internal an public constructors that allow for creating metadata items in the unlocked state
* A few mutating methods and properties that it is not possible to call on newly constructed items but it is possible to invoke on an existing item inside a Code First convention (i.e. before the model is locked) such as EdmFunction.AddParameter
* A few mutating methods that we added for specific designer scenarios that could not be addressed in only public constructability, e.g. EntityType.AddNavigationProperty, which was added to deal with circular references.
In the future we should try to come up with more consistent patterns that cover all of our own internal needs and also customer scenarios. We only scratched the surface for what could be done with model conventions, and in scenarios in which customers can create models from scratch.
Fundamentally all the work we did was driven by two different "customers" that had different requirements:
* __Designer:__ The metadata usage patterns of the EF designer did not really need mutability but just public constructability (in fact, mutability for the designer is dangerous because unlike EF code first the designer does not define an entry point for making the whole model immutable by calling the SetReadOnly method in cascade). Also in some cases the designer needs to deal with unfinished models in which the XML for a specific item exists in the EDMX but is insufficient to construct an instance of the valid item in memory. Give those two requirements we went down the path of adding a bunch of 'Create' factory methods on metadata types that return already finished (i.e. locked) instances
* __Code First:__ The metadata usage patterns of EF code first generally use mutability but this mutability is not necessarily public because all the built-in conventions and discrete code first logic obviously has access to internals. Code First does define an entry point in which a model can transition to an immutable state, that is used when a DbModel is compiled into a DbCompiledModel, therefor it is safe in general in the Code First pipeline to leave objects as mutable.
We did not take the chance in EF6 to reconcile the requirements of public constructability and mutability, therefore we ended up with:
* Factory methods that at least in the majority of cases return locked objects
* A mix of internal an public constructors that allow for creating metadata items in the unlocked state
* A few mutating methods and properties that it is not possible to call on newly constructed items but it is possible to invoke on an existing item inside a Code First convention (i.e. before the model is locked) such as EdmFunction.AddParameter
* A few mutating methods that we added for specific designer scenarios that could not be addressed in only public constructability, e.g. EntityType.AddNavigationProperty, which was added to deal with circular references.
In the future we should try to come up with more consistent patterns that cover all of our own internal needs and also customer scenarios. We only scratched the surface for what could be done with model conventions, and in scenarios in which customers can create models from scratch.