ngs-doo / revenj

DSL Platform compatible backend
https://dsl-platform.com
BSD 3-Clause "New" or "Revised" License
268 stars 44 forks source link

Implement IEditableObject #112

Closed Kobus-Smit closed 2 years ago

Kobus-Smit commented 6 years ago

Hi @zapov

Can the Revenj compiler generate client classes that implement IEditableObject?

This would be very useful to enable rollback functionality in data grid components, for example: [1] [2] [3]

Would be much appreciated.

zapov commented 6 years ago

C# server code has a notion of track changes, which keeps around original version of the object. I guess that could be used to implement such a feature in a generic manner.

But I guess you need this on a C# client target? I don't think it support track changes in such a manner. But it makes sense to have that feature in client target also.

Kobus-Smit commented 6 years ago

C# client correct.

I'm currently inheriting from the client class and implementing IEditableObject myself (otherwise I can't use the nice XtraGrid component) Simply using backup variables as in the DevExpress example (not as in the MSDN link), and it works but it's repetitive plumbing and casting etc. :-)

On Mon, 10 Sep. 2018, 8:52 pm zapov, notifications@github.com wrote:

C# server code has a notion of track changes, which keeps around original version of the object. I guess that could be used to implement such a feature in a generic manner.

But I guess you need this on a C# client target? I don't think it support track changes in such a manner. But it makes sense to have that feature in client target also.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ngs-doo/revenj/issues/112#issuecomment-419871829, or mute the thread https://github.com/notifications/unsubscribe-auth/AKvfePLwNNwP6E8cz0NJV_I_ZgYtvhMqks5uZkRtgaJpZM4WghZb .

zapov commented 6 years ago

What you can do is define a mixin with some custom code. You can add custom code via the mapping of an implementation feature, eg:

module test {
  mixin EditableObject {
    implements c# 'System.ComponentModel.IEditableObject' {
      <# 
        dynamic __original;
        void System.ComponentModel.IEditableObject.BeginEdit() { __original = this.Clone(); }
        void System.ComponentModel.IEditableObject.CancelEdit() { UpdateWithAnother(this.__original); }
        void System.ComponentModel.IEditableObject.EndEdit() { }
      #>;
    }
  }
  root Agg {
    string x;
    Value v;
    has mixin EditableObject;
  }
  value Value {
    int i;
  }
}

Now you can specify that mixin on every appropriate object. But currently there are some downsides to this:

I guess I should add client as a target for implementation which would resolve your problem. But try this out with latest compiler and let me know if that resolves your problem.

Kobus-Smit commented 6 years ago

Thanks @zapov I'm going to try it.

I'll have to remember to add it to each (probably most) objects, making the DSL more verbose.

What are your reasons for not generating that as part of the client code?

On Tue, 11 Sep. 2018, 7:40 am zapov, notifications@github.com wrote:

What you can do is define a mixin with some custom code. You can add custom code via the mapping of an implementation feature, eg:

module test { mixin EditableObject { implements c# 'System.ComponentModel.IEditableObject' { <# dynamic original; void System.ComponentModel.IEditableObject.BeginEdit() { original = this.Clone(); } void System.ComponentModel.IEditableObject.CancelEdit() { UpdateWithAnother(this.__original); } void System.ComponentModel.IEditableObject.EndEdit() { }

>;

}

} root Agg { string x; Value v; has mixin EditableObject; } value Value { int i; } }

Now you can specify that mixin on every appropriate object. But currently there are some downsides to this:

  • UpdateWithAnother is a method only available in client code
  • there is no way to specify c# only for client target

I guess I should add client as a target for implementation which would resolve your problem. But try this out with latest compiler and let me know if that resolves your problem.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ngs-doo/revenj/issues/112#issuecomment-420070692, or mute the thread https://github.com/notifications/unsubscribe-auth/AKvfeL3x45LmceeXss9PfBsq_JnGIcfJks5uZtxggaJpZM4WghZb .

Kobus-Smit commented 6 years ago

Yes the mentioned downsides makes it difficult to use in the case where you have one .sln with the client, common and server .csprojs:

image

zapov commented 6 years ago

you can apply mixin on objects automatically by doing something like

apply on all aggregates;

I'll look into adding additional target soon.

Kobus-Smit commented 6 years ago

Ok cool, I'm discovering/learning more about Revenj every time you respond. Thanks, much appreciated @zapov

zapov commented 6 years ago

I've released a new compiler. There is now a client target which you can use.

Kobus-Smit commented 6 years ago

Thanks @zapov

Where in the dsl do I use that client target?

Kobus-Smit commented 6 years ago

Ah implements client

Kobus-Smit commented 6 years ago

Resolved, thanks again @zapov

Kobus-Smit commented 2 years ago

Now you can specify that mixin on every appropriate object. But currently there are some downsides to this:

  • UpdateWithAnother is a method only available in client code

Hi @zapov , hope you are well.

Would it be possible for the compiler to also generate the UpdateWithAnother method for POCOs? We were using the Client library in our .NET framework project, and then after migrating to .NET Core we used the POCO DotNetStandard library.

The only missing thing now is the UpdateWithAnother method does not exist when we use

  implements c# 'System.ComponentModel.IEditableObject' { 
    <# 
    dynamic __original;
    void System.ComponentModel.IEditableObject.BeginEdit()  { __original = this.Clone(); }
    void System.ComponentModel.IEditableObject.CancelEdit() { UpdateWithAnother(this.__original); }
    void System.ComponentModel.IEditableObject.EndEdit()    { }
    #>; 
  } 
zapov commented 2 years ago

I would need to extend compiler to support something like that. And it would kind of conflict with this client and server version of change tracking.

If you can implement something to keep track of this objects and reset them back from clones that sounds much better than relying on the compiler support.

Eg, take snapshot via clone. Replace objects in place via snapshots if cancel fails.

Its better if you architecture your app that way, than to rely on this POCO resets... as this makes them... not so much POCO.

Kobus-Smit commented 2 years ago

Yes. I hear you, but I cannot think how to implement it otherwise. For the thirdparty UI components to correctly rollback, the objects must implement IEditableObject.

The mixin worked great with the C# client lib, but there is no C# client lib for .NET Core right? So that is why I've just used the POCO lib.

zapov commented 2 years ago

I would be more interested in updating client lib to work with new .NET than adding this copy for POCO only. Is this something which would resolve your issue?

Kobus-Smit commented 2 years ago

Yeah that would resolve the issue.

We've used the client lib before but that was with the WCF service. We've replaced WCF with gRPC in .NET 5/6 using https://github.com/Cysharp/MagicOnion so we'll just depend on the POCO part and the UpdateWithAnother method.

zapov commented 2 years ago

I thought I released this last year :( Will do it soon.

Kobus-Smit commented 2 years ago

Cheers, thanks mate

On Thu, 1 Sept 2022, 4:31 pm zapov, @.***> wrote:

I thought I released this last year :( Will do it soon.

— Reply to this email directly, view it on GitHub https://github.com/ngs-doo/revenj/issues/112#issuecomment-1233806083, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACV566B66MVHRGYQCDRKQF3V4BEU3ANCNFSM4FUCCZNQ . You are receiving this because you modified the open/close state.Message ID: @.***>

zapov commented 2 years ago

Its up: https://www.nuget.org/packages/Revenj.Client

Kobus-Smit commented 2 years ago

Thanks @zapov

I'd probably have to use the cli to generate the client dll? I'll have a look next week.

Because the Client lib does not have a DotNetStandard build type as POCO and Postgres, so there are errors.

image

image

image

zapov commented 2 years ago

I released new VS plugin which adds this option to client.

Kobus-Smit commented 2 years ago

Thanks mate.

I've used the new VS plugin and the latest compiler and get CS0656 Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

image

image

It compiles after adding the Microsoft.CSharp NuGet (SO)

Can you also gen this for the client project?

<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
zapov commented 2 years ago

You should be able to include this dependency in the deps at client page for Nuget Just put it after revenj.client 0.9.0

Kobus-Smit commented 2 years ago

Ah of course :-)

image