Context
Found while validating ECoreNetto 7.0.9 against the Eclipse Capella 7.0 metamodel for STARIONGROUP/capella4net#2, where 21 interdependent .ecore files are loaded through one ResourceSet.
Problem
ResourceSet.CreateResource(uri) unconditionally creates and registers a new Resource, even when a resource with the same URI is already in Resources. This happens naturally when a caller registers files one by one while demand-loading has already pulled some of them in as dependencies of earlier files:
foreach (var file in ecoreFiles)
{
var resource = resourceSet.CreateResource(new Uri(file)); // duplicate if demand-loaded earlier
resource.Load(null);
}
Once two resources share a URI, every internal lookup via this.ResourceSet.Resources.SingleOrDefault(x => x.URI == resourceUri) throws InvalidOperationException: Sequence contains more than one matching element, poisoning all subsequent resolution in the set.
Suggested direction
Make CreateResource return the existing resource for an already-registered URI (EMF behaviour is getResource(uri, loadOnDemand) semantics), or throw a descriptive exception at creation time instead of corrupting the set.
Context
Found while validating ECoreNetto 7.0.9 against the Eclipse Capella 7.0 metamodel for STARIONGROUP/capella4net#2, where 21 interdependent
.ecorefiles are loaded through oneResourceSet.Problem
ResourceSet.CreateResource(uri)unconditionally creates and registers a newResource, even when a resource with the same URI is already inResources. This happens naturally when a caller registers files one by one while demand-loading has already pulled some of them in as dependencies of earlier files:Once two resources share a URI, every internal lookup via
this.ResourceSet.Resources.SingleOrDefault(x => x.URI == resourceUri)throwsInvalidOperationException: Sequence contains more than one matching element, poisoning all subsequent resolution in the set.Suggested direction
Make
CreateResourcereturn the existing resource for an already-registered URI (EMF behaviour isgetResource(uri, loadOnDemand)semantics), or throw a descriptive exception at creation time instead of corrupting the set.