Art Of Programming

musings by Dmytrii Nagirniak

ECO GlobalData in OCL

One of the common things in any application is getting access to current user or other session-like information from the domain objects. It can be usually done with static members (the horrible thing!), injecting a service (so there should a place to get the service from, like dependency injection framework).

I’ve done just using a bit mixed solution with ECO. So there’s a service registered in the ECO space (lifetime is the same as EcoSpace’ one) and there’s an OCL operation that accesses the modeled global data object.

Just putting a not on how to get access to the transient global data object. It doesn’t use the service but just relies on ECO internals in full.

public class GetGlobalDataInstanceOcl : OclOperationBase {
    protected override void Init() {
        var globalObjectType = GetOclType();
        IOclType[] parameters = new IOclType[] {
            globalObjectType
        };
        InternalInit("getInstance", parameters, globalObjectType);
        IsTypeOperation = true;
    }
 
    private IOclType GetOclType() {
        var classifier = Support.Model.GetClassifierByType(typeof(GlobalData));
        return Support.GetOclTypeFor(classifier);
    }
 
    public override void Evaluate(IOclOperationParameters oclParameters) {
        var allGlobalDataInstances = Support.ExtentService.AllInstances(typeof(GlobalData));
        if (allGlobalDataInstances.Count != 1) {
            // Something wrong with it... Let's just throw for now...
            throw new InvalidOperationException(string.Format("Global data object must have one and only one instance, but has {0}. It must be validated before using it in OCL.", allGlobalDataInstances.Count));
        }
        oclParameters.Result.SetOwnedElement(allGlobalDataInstances[0]);
    }
}
 
[Test]
public void GlobalDataInstance_IsAccessibleInOcl_AndReturnsSameInstance() {
    var space = InitTestWorkSpace();
    space.GetEcoService<IOclTypeService>().InstallOperation(new GetGlobalDataInstanceOcl());
 
    var data = new GlobalData(space);
    var ocl = space.Ocl;
    Assert.AreSame(data, ocl.Evaluate("GlobalData.getInstance()").AsObject, "Invalid instance");
    Assert.AreSame(ocl.Evaluate("GlobalData.getInstance()").AsObject, ocl.Evaluate("GlobalData.getInstance()").AsObject, "Same object should be returned.");
}

Enjoy!

Comments