microsoft / Chakra-Samples

Repository for Chakra JavaScript engine related samples.
MIT License
216 stars 84 forks source link

Overcome 1 Interface limitation for projected classes to Javascript? #67

Open leanalcabasa opened 7 years ago

leanalcabasa commented 7 years ago

Hello,

Not sure if this is the best place to ask this (is there a forum for chakra)?

I have a problem with the limitation of only having the 1st interface projected to Javascript. I would like to know if there are any workarounds / methods of solving it.

I have around 20 classes I want to access in Javascript. These 20 classes inherit from a BaseModel, which contains code that are important and used by all 20 classes. Below is a simple example:

public class Category : BaseModel
{
    public string Title {get;set;}
    public string Description {get;set;}
}

public class Item : BaseModel
{
    public string Title {get;set;}
    public string Price {get;set;}
}

public class BaseModel : INotifyPropertyChanged, IParentableViewModel
{
    //Some Important Methods that are shared between around 20 Models
}

If I want to access it in Javascript, I would have to create BaseModel for ALL 20 of the classes. This is because Javascript can only see the properties / methods of the 1st Interface. So then my code becomes something like:

public class CategoryBaseModel : ICategoryModel, INotifyPropertyChanged, IParentableViewModel
{
    //Important Methods gets duplicated between CategoryBaseModel and ItemBaseModel making it harder to maintain
}

public class ItemBaseModel : IItemModel, INotifyPropertyChanged, IParentableViewModel
{
    //Important Methods gets duplicated between CategoryBaseModel and ItemBaseModel making it harder to maintain
}

Which becomes hard to maintain, especially since I have around 20 methods.

I am looking if I can override the setter for Javascript but not sure how to do it. The idea is this:

//I want to override something like this. 
//whenever I call category.someProperty = someValue; in Javascript, it goes through this.
//When it goes through this, I can then call the SetProperty method for unknown properties in the interface
public bool JavaScriptPropertySet(object, propertyName, Value)
{
    if(object.hasProperty(propertyName))
    {
        //Set PropertyName
    }
    else
    {
        object.setProperty(propertyName, Value);
    }
}

And then I can define my classes to be simpler like this:

public interface IBaseViewModel
{
    string Title {get;set;}
    void SetProperty(propertyName, Value);
}

public class BaseModel : IBaseViewModel, INotifyPropertyChanged, IParentableViewModel
{
    //important methods

    public void SetProperty(propertyName, Value)
    {
        SetPropertyInternal(propertyName, Value);
    }

    public virtual void SetPropertyInternal(propertyName, Value)
    {
    }
}

public class Category : BaseModel
{
    public override void SetPropertyInternal(propertyName, Value)
    {
        if(propertyName == 'description')
            this.description = Value;
    }
}

Is there such a way?

Thank you

liminzhu commented 7 years ago

@leanalcabasa ChakraCore might be the better place to discuss this 😄 so please open the same issue there. Btw are you using Chakra and ChakraCore, and how do you project the classes to JS?

leanalcabasa commented 7 years ago

Thanks liminzhu! We are actually using ChakraBridge for our UWP project. We project the classes using Interfaces. That is why we are trying to overcome the 1 interface limitation because Javascript can only see the properties / methods of the 1st interface of the class. The problem is, we have a BaseClass that is inherited by a lot of other classes.