ExternalId with PersistenceMapperMemory

CapableObjects Forums SupportForum ExternalId with PersistenceMapperMemory

This topic contains 5 replies, has 2 voices, and was last updated by  krilbe 5 years, 2 months ago.

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #5267 Score: 0

    krilbe
    Participant

    For some unit tests, I create my EcoSpace with PM replaced with PersistenceMapperMemory. Works fine, but now I need to test code that uses ExternalId. But when I call the extension method IEcoObject.ExternalId(), I get an exception:

    System.InvalidOperationException: ‘MappingProvider has not been initialized’

    What could be causing this?

    The code that creates the EcoSpace looks like this:

    SyncHandler sh = new SyncHandler();
    PersistenceMapperMemory pm = new PersistenceMapperMemory();
    pm.SyncHandler = sh;
    return new MyEcoSpace(pm);

    And that constructor looks like this:

    public DiamondsEcoSpace(PersistenceMapper pm) : base()
    {
        InitializeComponent();
        persistenceMapperSharer = null;
        PersistenceMapper = pm;
        OtherInitializations();
    }
    #5268 Score: 0

    krilbe
    Participant

    I tested with my regular PM and the code works in that case.

    Maybe PersistenceMapperMemory just doesn’t support external id:s?

    In that case, how would I implement such a service to be able to test my code?

    I would prefer a mock (NSubstitute), but how do I get it “installed” so it’s used in my test EcoSpace?

    #5269 Score: 0

    Peter Buchmann
    Participant

    When I use an EcoSpace for testing, I don’t use the normal EcoSpace. I use a TestEcoSpace that is configured using a PersistenceMapperMemory. And: PersistenceMapperMemory supports external IDs perfectly. You only have to update the database as you would do for an ordinary EcoSpace after creating data in the EcoSpace.

    I’ve made very good experiences using SpecFlow (behavior driven development) by using Gherkin and entering test data in a table form.

    #5270 Score: 0

    krilbe
    Participant

    Thanks Peter. Good to know. So, then I wonder what might be wrong in my case… Why do I get that exception?

    Can you post your setup code for that memory mapped EcoSpace of yours?

    #5271 Score: 0

    krilbe
    Participant

    Trying to debug the issue, I found that during EcoSpace construction, this method gets called:

    protected override Eco.Services.Impl.ExternalIdServiceBase CreateExternalIdService(Eco.UmlRt.IEcoTypeSystem typeSystem)
    {
      return new Eco.Services.Impl.ExternalIdServiceImpl_DbType(typeSystem, (DiamondsPMP.Instance.PersistenceMapper as Eco.Persistence.AbstractPersistenceMapperDb).EffectiveRunTimeMappingProvider);
    }

    I think I added that override when I wanted to use the DB type discriminator rather than the internal type index for my external id:s.

    Since this gets called in the constructor’s base() call, I have no way to pass any parameters or settings to it. Instead, I would need to change the ExternalIdService afterwards, in my custom constructor code. But I fail to find info about how to hook it up. Is it sufficient to simply register a new instance of ExternalIdServiceBase to the service provider?

    Another option would be to have a static flag in MyEcoSpace class, that would alter what the method above returns.

    Suggestions?

    #5272 Score: 0

    krilbe
    Participant

    So I ended up creating a static method MyEcoSpace.CreateMemoryMapped which sets a private static flag before instantiating the EcoSpace. In the CreateExternalIdService override I check this static flag, and return a regular ExternalIdServiceImpl if set, otherwise the ExternalIdServiceImpl_DbType that I want for regular use. Seems to work.

    If anyone can come up with a simpler or less ugly solution, feel free to comment. 🙂

    • This reply was modified 5 years, 2 months ago by  krilbe.
Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.

Comments are closed.