Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Cuntpunch
Oct 3, 2003

A monkey in a long line of kings

SimonChris posted:

You can also use nested classes, but I have never tried this and can't vouch for the results: https://www.tutorialspoint.com/what-is-the-chash-equivalent-of-cplusplus-friend-keyword

The semantics of that can get awkward, can't it? It seems like you end up in one of a few situations, all of which feel weird:
- If the nested class is public, you've got the weird OuterType.NestedType() ctor or static using syntax.
- If the nested class is private, you've got to have a higher-up base class or interface that's public.

Adbot
ADBOT LOVES YOU

insta
Jan 28, 2009

Boz0r posted:

I have a constructor that should only be called from a factory. How do I give the other devs a warning and refer them to the factory(also suppress the warning in the factory) if they try to use it? I was thinking of using Obsolete, but the constructor isn't obsolete.

Can you #pragma ignore the warning in the factory?

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Make the constructor private and make the factory a static method on the class?

WorkerThread
Feb 15, 2012

just write an analyzer that checks for correct usage and emits an error othereise; ez

rarbatrol
Apr 17, 2011

Hurt//maim//kill.

SimonChris posted:

You can also use nested classes...

I've done something like this in the past:
1. Make the constructor for your class protected
2. Inherit from the class as a private nested class inside of the factory class
3. Return instances of the inherited class

That prevents impatient people from directly calling the constructor, at the very least. You can make use of the other suggestions as well, depending on how hard you want it to be to create the thing on its own. It'll always be possible to a degree, but most people wont care that much.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I'm having to do some rather onerous reflection square-peg-round-hole stuff for this interpreter I'm writing. In this particular case, I'm trying to subscribe a .NET object's function to a matching event, but due to it happening in the interpreter's context, I'm kind of stuck with some wrappers that obfuscate this. Even if that wasn't directly necessary in this case, I'd have to suck this up if I tried to get one of the interpreted functions subscribed to the .NET event anyways.

The issue comes down to the personal Hell of reflection that I have created. What I have is something I know that I can invoke with a an object[] containing all the parameters I need to fill. The wrapper would deal with the boxing/unboxing if necessary. This however has completely knocked out the normal signature for the function. The delegate I try to create for this then has a signature assuming arguments of object[]. The event is using a delegate that takes an int in this case. The .NET runtime definitely mad about this.

If you want to see what's going on, here it is, but Trigger Warning: contains eye bleeding:
code:
dynamic left = context.DataStack.Pop();
dynamic right = context.DataStack.Pop();

var leftEvent = left as EventInfo;
var rightCall = right as WrappedCodeObject;
if (leftEvent != null)
{
    // It's coming in as a WrappedCodeObject so we have to turn it into a call that can accept the arguments we're expecting. We'll pencil in
    // the interpreter and the frame. This should then break down the function into something that just takes the arguments we originally expect.
    // BTW That frame could be an issue since maybe it won't tell us the right place when we actually trigger it. Stay tuned.
    MethodInfo rightCurriedMethodInfo;
    var eventMethodInfo = leftEvent.EventHandlerType.GetMethod("Invoke");       // Return signature is probably void but we gotta make sure.
    if (eventMethodInfo.ReturnType == typeof(void))
    {
        rightCurriedMethodInfo = (new Action<object[]>(args =>
        {
            rightCall.Call(this, context, args);
        })).Method;
    }
    else
    {
        // Oh wow! It wasn't a void function!
        rightCurriedMethodInfo = (new Func<object[], object>(args =>
        {
            return rightCall.Call(this, context, args);
        })).Method;
    }
    var rightDelegate = Delegate.CreateDelegate(leftEvent.EventHandlerType, rightCall.GetObjectInstance(), rightCurriedMethodInfo);
    leftEvent.AddEventHandler(left, rightDelegate);
}

When I try to run CreateDelegate, I get an ArgumentException "Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type." I'm pretty sure that's because the event is void(int) but I'm technically feeding it void(object[]) where object[] just has a single element containing the list.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Forgive me if it's a stupid question, I didn't take the time to understand all of that, but couldn't you just pass around object instead of object[] ? An array is an object. You can just require that the invokee accept object and it has to know that it'll be of type object[] (or whatever else).

Mr Shiny Pants
Nov 12, 2012

a hot gujju bhabhi posted:

This is a good example of why throwing functional programming at every problem is not gonna work.

Why? It is exactly where it shines. Your model is readonly, the view renders the model, after some event the model gets updated etc. All other side effects are gone.

EssOEss posted:

That sounds like it is worth trying. While MVVM and MVC are okay, I always felt like one could do better, so experimenting with this model might be of interest. Is there some straightforward way to apply this model to .NET UI frameworks? WPF/ASP.NET/WinForms/whatever? What should I do to avoid reinventing wheels when I experiment with it?

Try Fable or Fabulous with Xamarin forms. It works really well.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Hammerite posted:

Forgive me if it's a stupid question, I didn't take the time to understand all of that, but couldn't you just pass around object instead of object[] ? An array is an object. You can just require that the invokee accept object and it has to know that it'll be of type object[] (or whatever else).

The object[] represents all the arguments to be conveyed to the call in the order that matches the parameters. If I ignore the event shenanigans and just look at it as a call, I'm wrapping a .NET call that takes 0+ arguments. The script that's running is going to load up a bunch of arguments it was given in the script code. I take that as an array of objects because I don't really have any lower baseline for taking them into the all-purpose wrapper. I think Invoke() takes that array without a problem but I'd have to look a the source to tell, and that's despite all the functions taking, like, (int, string, SomeActualClass) and stuff like that.

putin is a cunt
Apr 5, 2007

BOY DO I SURE ENJOY TRASH. THERE'S NOTHING MORE I LOVE THAN TO SIT DOWN IN FRONT OF THE BIG SCREEN AND EAT A BIIIIG STEAMY BOWL OF SHIT. WARNER BROS CAN COME OVER TO MY HOUSE AND ASSFUCK MY MOM WHILE I WATCH AND I WOULD CERTIFY IT FRESH, NO QUESTION

Mr Shiny Pants posted:

Why? It is exactly where it shines. Your model is readonly, the view renders the model, after some event the model gets updated etc. All other side effects are gone.

Re-rendering the entire view on every change is often undesirable.

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

New Yorp New Yorp posted:

In general, desktop GUIs are super dead. It's all web apps and mobile apps nowadays. That said, Microsoft brought WPF and Winforms to .NET Core 3, so WPF would probably be the recommended path forward for desktop GUI apps. In general, if it's not in .NET Core or coming to .NET Core, it's on life support.

Desktop guis in desktop languages are dead. Desktop guis in Javascript are alive.

Much easier to hire a bunch of bootcampers to crank out react components that are web/native cross platform than to train them on multiple languages and platforms that suck to develop on for gui code

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Rocko Bonaparte posted:

I'm having to do some rather onerous reflection square-peg-round-hole stuff for this interpreter I'm writing. In this particular case, I'm trying to subscribe a .NET object's function to a matching event, but due to it happening in the interpreter's context, I'm kind of stuck with some wrappers that obfuscate this. Even if that wasn't directly necessary in this case, I'd have to suck this up if I tried to get one of the interpreted functions subscribed to the .NET event anyways.

An update on something I tried. I tried to dabble with a DynamicMethod for this. I can properly declare one but then I'm like a dog that caught the car. I don't know what happens next. I've love to be able to define a lambda that takes in the parameters as an array and maps them to my call, but I have no idea what to do to make that happen. This also looks like a horrible precipe and maybe I shouldn't be standing here because DynamicMethod is all about emitting IL code manually.

Mr Shiny Pants
Nov 12, 2012

a hot gujju bhabhi posted:

Re-rendering the entire view on every change is often undesirable.

Fable uses a Virtual Dom so it diffs the update, they are working on something like this for other GUI frameworks.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Final update before I descend into the abyss:

Rocko Bonaparte posted:

This also looks like a horrible precipe and maybe I shouldn't be standing here because DynamicMethod is all about emitting IL code manually.

I looked at what IronPython was doing for this. It was... emitting IL code. Great. I guess this is me now.

Kuule hain nussivan
Nov 27, 2008

I'm having a really silly problem with Dapper and SQLite and I don't know why.

I'm basically trying to do the following...

INSERT INTO x (y)
SELECT * FROM (VALUES ('z'), ('w'))
EXCEPT
SELECT y FROM x

And my code is

code:
const string insertQuery = @"INSERT INTO x (y)
                SELECT * FROM (VALUES @Values)
                EXCEPT
                SELECT y FROM x;";
            
try
{
	await connection.ExecuteAsync(insertQuery, new {
        	Values= string.Join(",", stuff.Select(v => $"('{v}')"))
         });
         connection.Close();
}
This throws an exception because SQLite complains that there's a syntax error near @Values, so for some reason Dapper isn't replacing it with the string value in parameters. However, if I do the following...

code:
const string insertQuery = @"INSERT INTO x (y)
                SELECT * FROM (VALUES (@Values))
                EXCEPT
                SELECT y FROM x;";
            
try
{
	await connection.ExecuteAsync(insertQuery, new {
        	Values= string.Join(",", stuff.Select(v => $"('{v}')"))
         });
         connection.Close();
}
...it works, but then the SQL is not what I want, as it will insert all the values in Values as a single row, rather than one value per row. I'm sure it's something simple, but I've been banging my head against the wall for 30 minutes now.

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

I haven't used Dapper in anger, but I would guess you want to directly pass in an array or other collection instead of manually doing string concatenation, which is exactly what SQL parameters exist to avoid doing.

SQL parameters are generally typed (although SQLite doesn't enforce column types, I believe its SQL dialect is still typed). The second query runs because the database engine expects a string parameter. The first one expects a table or array, and you're passing in a string.

Hairy Marionette
Apr 22, 2005

I am not immune to propaganda

NihilCredo posted:

I haven't used Dapper in anger, but I would guess you want to directly pass in an array or other collection instead of manually doing string concatenation, which is exactly what SQL parameters exist to avoid doing.

SQL parameters are generally typed (although SQLite doesn't enforce column types, I believe its SQL dialect is still typed). The second query runs because the database engine expects a string parameter. The first one expects a table or array, and you're passing in a string.

I don’t think SQLite supports table or array parameters.

mortarr
Apr 28, 2005

frozen meat at high speed
I'm after some advice on copying files (typically images) from usb-attached android / iphones to local disk.

If I use the normal windows file dialog, it is not possible to select multiple files from these kinds of devices even though it is possible to in windows explorer. I have found the windows api codepack, which has an explorer-like window that does enable selection of multiple files on a usb device.

The result of the selection operation is a list of ShellObject. The ShellObject class has features so I can get thumbnails and properties, such as the "parsing name" and a human-readable name.

The parsing name looks like this:
::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_22b8&pid_2e82#zy322kldjb#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\SID-{10001,,26401026048}\{00000009-0001-0001-0000-000000000000}\{00000075-0001-0001-0000-000000000000}\{00005461-0001-0001-0000-000000000000}

The human-readable name looks like this:
This PC\Device Name\Internal shared storage\DCIM\Camera\file.png

From here I'm doing something that feels pretty fragile... bashing the parsing name and using the PortableDeviceApiLib to copy the file:
code:
    private static void CopyOneFile()
    {
      // hard coded values at the moment
      var deviceId = @"\\?\usb#vid_22b8&pid_2e82#zy322kldjb#{6ac27878-a6fa-4155-ba85-f98f491d4f33}";
      var sourceItemGuidString = "{00005461-0001-0001-0000-000000000000}";
      var destinationPath = @"C:\Test\";
      var fileName = "IMG_Test.jpg";
      var size = 3738545;

      var device = new PortableDeviceCollection().FirstOrDefault(d => d.DeviceId == deviceId);
      if (device == null)
      {
        // this just gets the first android device, as deviceId changes each time the device is connected
        var devices = new PortableDeviceCollection();
        devices.Refresh();
        device = devices.First();

        if (device == null)
        {
          throw new FileNotFoundException();
        }
      }

      // fileId = "o5461";
      var fileId = "o" + sourceItemGuidString.Replace("{", string.Empty).Replace("}", string.Empty).Split('-')[0].TrimStart('0');
      device.TransferContentFromDevice(fileId, size, destinationPath, fileName);

      // device.Disconnect(); // not sure if this is necessary
    }
I think introducing a separate api and bashing the file name is dumb as hell - it works, but I'm not confident enough to release into production!

I'd prefer to work with the ShellObjects directly, but I can't seem to find any relevant CopyTo, GetBytes or GetStream methods I can use. Google gives back a lot of c++ stuff or low level windows api docs back, but I don't have any experience there at all.

mortarr fucked around with this message at 02:34 on Feb 19, 2020

Hughmoris
Apr 21, 2007
Let's go to the abyss!
Thanks for the advice/thoughts on what GUI to start with.

Dumb question if I choose to pursue using a webapp instead of something like WPF:

Is it easy for webapps (such as a Blazor client-side app) to modify files on my local machine? An idea for my first app is a program that will read a folder full of media files on my laptop, present it as a fancy list to the user, and the user can rename the file and save.

mystes
May 31, 2006

Hughmoris posted:

Thanks for the advice/thoughts on what GUI to start with.

Dumb question if I choose to pursue using a webapp instead of something like WPF:

Is it easy for webapps (such as a Blazor client-side app) to modify files on my local machine? An idea for my first app is a program that will read a folder full of media files on my laptop, present it as a fancy list to the user, and the user can rename the file and save.
If you use client side blazor, the code running in the browser won't be able to modify files, but you will presumably also be running the server on the same machine so you just have to have to do the actual modifying of files from the server. If you use Blazor Server all the code is actually running on the server so you don't have to even think about this distinction.

You can also use WebWindow which is a cross platform wrapper for lauching Blazor Server in a window like an electron application.

mystes fucked around with this message at 13:59 on Feb 19, 2020

namlosh
Feb 11, 2014

I name this haircut "The Sad Rhino".

Hughmoris posted:

Thanks for the advice/thoughts on what GUI to start with.

Dumb question if I choose to pursue using a webapp instead of something like WPF:

Is it easy for webapps (such as a Blazor client-side app) to modify files on my local machine? An idea for my first app is a program that will read a folder full of media files on my laptop, present it as a fancy list to the user, and the user can rename the file and save.

Personally, I would suggest starting out with something like WPF. It’s mature, it has markup based UI: XAML vs HTML. And it’ll be supported for a while as it’s getting ported to .net core last I heard.
While I can understand wanting to jump into web I think it would be a mistake as there’s a ton more complexity that could inhibit learning the basics.
You also won’t run into any of the issues/bugs you would if you started out with blazor .net core 3.1 (the latest). While learning, you should be concerned with finding bugs in your own code, not the frameworks.

Just my opinion :)

nielsm
Jun 1, 2009



mortarr posted:

I'm after some advice on copying files (typically images) from usb-attached android / iphones to local disk.

...

I'd prefer to work with the ShellObjects directly, but I can't seem to find any relevant CopyTo, GetBytes or GetStream methods I can use. Google gives back a lot of c++ stuff or low level windows api docs back, but I don't have any experience there at all.

You probably need to use IFileOperation for that.

mortarr
Apr 28, 2005

frozen meat at high speed

nielsm posted:

You probably need to use IFileOperation for that.

Yeah, I've since learned that the windows api codepack misses a bunch of functionality, so the file discovery and then copy workflow I'm working on ends up involving a lot of backflips and poo poo across a couple of api's and nuget packages - still not convinced the way I'm doing it is the best, but I think I've got a prod-ready solution now. Kind-of wishing I had better facility with c++ right about now so I could read and translate some examples that are fully c++, but in 20+ years of cutting code, this is about as hairy a shell/com/interop dealio as I've ever needed to manage.


The actual workflow I'm supporting is:
- Outside my app, a user takes some pictures on their phone, camera, whatever, then attaches the device to a pc
- Using my app, the user will then...
- Select the pictures
- Give them a readable name and add metadata, eg licensing, key features or people, notes etc
- Upload to CMS app


What slipped through my testing when I built this was that the standard file-browse / select dialog in VS only allows you to select one file from usb attached devices that don't show up like network drives - eg. android or iphones. The second thing that got me was that although the api codepack lets you get a thumbnail of the image from a selected file, there was no easy way to either get access to its data directly or copy it local - that's what my question was about. I had visions of needing to go back to the client and say I didn't have the skills to build what they wanted, but hopefully all good now.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Are there any MSIL warlocks in here that can share their toolchain? I'm using ILSpy and LINQPad to view and test out various code between C# and MSIL. It mostly works but I'm getting bit by a lot of stuff that seems to require street smarts more than anything else. Maybe that's all there is to it. Most recently, I figured out the box opcode needs a type argument. I wasn't emitting one so my disassembly would get totally garbled around it. I'm guessing you just get a good set of eyes for that kind of thing, but I want to hope that there are extra things I can do in generation and/or different tools and techniques that can point out when I hosed up. When you run stuff like that, the exceptions you get are completely useless, so I can't count on them.

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

Rocko Bonaparte posted:

Are there any MSIL warlocks in here that can share their toolchain? I'm using ILSpy and LINQPad to view and test out various code between C# and MSIL. It mostly works but I'm getting bit by a lot of stuff that seems to require street smarts more than anything else. Maybe that's all there is to it. Most recently, I figured out the box opcode needs a type argument. I wasn't emitting one so my disassembly would get totally garbled around it. I'm guessing you just get a good set of eyes for that kind of thing, but I want to hope that there are extra things I can do in generation and/or different tools and techniques that can point out when I hosed up. When you run stuff like that, the exceptions you get are completely useless, so I can't count on them.

i use https://sharplab.io/ but what are u using msil for directly. this smells bad

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Malcolm XML posted:

i use https://sharplab.io/ but what are u using msil for directly. this smells bad

I'm trying to add an ability to attach my interpreter code to .NET delegates--particularly methods--of arbitrary signatures. The interpreter just takes a pile of objects for calls into its stuff. I need to present to .NET a method with a signature compatible with the delegate to which I'm trying to associate this interpreter code. I have to scrape those arguments into an object array to pass to the interpreter. C# doesn't appear to have anything to do this directly. I looked at how IronPython handles the same and they also went into dynamic methods and code generation, but IronPython is also just making GBS threads out MSIL everywhere; they're not the best example. Elsewhere I saw a lot of comments about resorting to dynamic methods for events and callbacks for remote method invocation frameworks.

To make it worse, the call I want to invoke is associated with an instance of an object. I can't pass it to the call I generate because it breaks the signature. So I also create a class with a field and a constructor that will internalize the instance. I the instantiate that class and pass in the object that has the script state. The code being generated then has instructions to load that method that calls into the interpreter with the object array that is also being generated in the MSIL. So to reiterate, I don't have a way to explore the method signature of the delegate I'm generating as a list so I can pack it into an object array using C#. So I drop down to MSIL to I can just ldarg my way through and cram them into an object[].

If C# had some means of looking at a method's total arguments in its signature as a list of objects then I wouldn't have to do any of this. I also tried to get cute and just create a bunch of stubbed calls for (object), (object, object), (object, ...) but C# syntactically refused to attach methods with such general arguments to the delegates in the events.

As for the hackiness of this, I've kind of given up because I'm dealing with programming language shenanigans here so I've bumped into all kinds of edge cases and landmines I never would have expected. At this point, playing with another stack-based bytecode assembler is just more of the same since I'm already generating my own stack-based bytecode assembler for the interpreter. I wish I had a time machine to take me back to college when I was doing homework for my computer architecture class and thought that style of low-level code was bullshit.

Funking Giblet
Jun 28, 2004

Jiglightful!

Rocko Bonaparte posted:

If C# had some means of looking at a method's total arguments in its signature as a list of objects then I wouldn't have to do any of this. I also tried to get cute and just create a bunch of stubbed calls for (object), (object, object), (object, ...) but C# syntactically refused to attach methods with such general arguments to the delegates in the events.
Generic Arguments could help you here, there are tons of examples of .net abusing them to provide delegate method arguments.


Method<string, int, decimal>(string, int, decimal);

I've gone down the IL Emit route before to attach dynamic methods to do Datareader -> Object mapping.

No-one else understood it and I spent more time maintaining it than just creating a method!

Funking Giblet fucked around with this message at 00:04 on Feb 22, 2020

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

Rocko Bonaparte posted:

I'm trying to add an ability to attach my interpreter code to .NET delegates--particularly methods--of arbitrary signatures. The interpreter just takes a pile of objects for calls into its stuff. I need to present to .NET a method with a signature compatible with the delegate to which I'm trying to associate this interpreter code. I have to scrape those arguments into an object array to pass to the interpreter. C# doesn't appear to have anything to do this directly. I looked at how IronPython handles the same and they also went into dynamic methods and code generation, but IronPython is also just making GBS threads out MSIL everywhere; they're not the best example. Elsewhere I saw a lot of comments about resorting to dynamic methods for events and callbacks for remote method invocation frameworks.

To make it worse, the call I want to invoke is associated with an instance of an object. I can't pass it to the call I generate because it breaks the signature. So I also create a class with a field and a constructor that will internalize the instance. I the instantiate that class and pass in the object that has the script state. The code being generated then has instructions to load that method that calls into the interpreter with the object array that is also being generated in the MSIL. So to reiterate, I don't have a way to explore the method signature of the delegate I'm generating as a list so I can pack it into an object array using C#. So I drop down to MSIL to I can just ldarg my way through and cram them into an object[].

If C# had some means of looking at a method's total arguments in its signature as a list of objects then I wouldn't have to do any of this. I also tried to get cute and just create a bunch of stubbed calls for (object), (object, object), (object, ...) but C# syntactically refused to attach methods with such general arguments to the delegates in the events.

As for the hackiness of this, I've kind of given up because I'm dealing with programming language shenanigans here so I've bumped into all kinds of edge cases and landmines I never would have expected. At this point, playing with another stack-based bytecode assembler is just more of the same since I'm already generating my own stack-based bytecode assembler for the interpreter. I wish I had a time machine to take me back to college when I was doing homework for my computer architecture class and thought that style of low-level code was bullshit.

this is well beyond my msil hackery to see how it compiles to asm, so good luck goon

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Funking Giblet posted:

Generic Arguments could help you here, there are tons of examples of .net abusing them to provide delegate method arguments.


Method<string, int, decimal>(string, int, decimal);

I've gone down the IL Emit route before to attach dynamic methods to do Datareader -> Object mapping.

No-one else understood it and I spent more time maintaining it than just creating a method!

How does it work? Do I basically declare lots of variants of:
code:
public object PoopTime<A, B, C>(A a, B b, C c)
{
   return inner.Call(new object[] { a, b, c });   // inner is this evil thing I have to add
}
Do I just have a fleet of PoopTimes of A, A+B, A+B+C, A+B+C+D... that I write out? I am guessing then that I look at the event to which I'm pairing, and I pass the parameter information from reflection to the generic arguments when creating the method. I did weigh that and considered duplicating that could would be better than having a spot where I go MSIL-crazy.

Funking Giblet
Jun 28, 2004

Jiglightful!
There are limits to the length of generics but yeah, basically, and debugging is simple! (You just need T1, T2... not every type, and an invoke, at worst, simple caching will help the lookup as well).

Although when I look at your code, something polymorphic is screaming at me, but I can't place a finger on it.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Funking Giblet posted:

There are limits to the length of generics but yeah, basically, and debugging is simple! (You just need T1, T2... not every type, and an invoke, at worst, simple caching will help the lookup as well).

Although when I look at your code, something polymorphic is screaming at me, but I can't place a finger on it.

I'm getting metaprogramming vibes and I don't have good feels from that. Just to see if I can make it work with any confidence will mean require going up to, say, two arguments. However, then I have to think about matching to events that have a return value in the delegate. Or I can decide to now support that and throw an exception containing a manifesto expressing my dissatisfaction with using events that have a return type.

NiceAaron
Oct 19, 2003

Devote your hearts to the cause~

I'm not sure if I totally understood the overall problem, but if you do go the route of writing a bunch of similar methods with varying numbers of generic type arguments, consider writing a T4 template that spits out the code for all the overloads of your method. That solves the code duplication issue, because you're basically just writing the method code once in the T4 template. (At the cost of having to learn about and understand T4 templates...)

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Hahaha I feel like I'm just picking which way I'll end getting dragged out to The Hague.

adaz
Mar 7, 2009

Rocko Bonaparte posted:

Hahaha I feel like I'm just picking which way I'll end getting dragged out to The Hague.

Yeah to be honest unless you're, idk, an employee of Microsoft or working on some compiler somewhere you shouldn't ever really be touching IL code. I'm not sure, exactly, what program it is you're working on or what you're doing but a general programming rule is when you're swimming up against a framework THIS much you're probably solving the wrong problem or should pick a different framework.

If this is some fun personal project tho, go forth and commit thy sins tho! All that was from a perspective of "work"

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
It's a personal project, but then a pull request came in...

Xik
Mar 10, 2011

Dinosaur Gum

adaz posted:

when you're swimming up against a framework THIS much you're probably solving the wrong problem or should pick a different framework.

But this is Rocko's entire gimmick.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Xik posted:

But this is Rocko's entire gimmick.

Well, it's mostly my posting style for hobby projects--and I should probably just start prefacing when I'm talking about personal or work. When I'm messing around personally, I am usually coming into conflict with something I'm working on because I'm deliberately doing crazy, stupid stuff. So I honestly get irritated in those situations when I either get the "X instead of Y" answer or my question is willfully getting distorted as some kid trying to get homework help and not realizing how hard of a thing they're asking about; I basically got both on the MSDN forum when I asked about this whole situation.

Now for the task at hand, using Method<args...> as a binder seems fine:
code:
        public void GenericWrapper<Arg1>(Arg1 arg1)
        {
            Call(new object[] { arg1 });
        }

        public void WrapWithGeneric(MethodInfo dotNetMethod)
        {
            var dotNetMethodParamInfos = dotNetMethod.GetParameters();

            // Just gunning for one arg with no return type for now.
            var genericWrapper = typeof(WrappedCodeObject).GetMethod("GenericWrapper");
            var realizedWrapper = genericWrapper.MakeGenericMethod(dotNetMethodParamInfos[0].ParameterType);
            realizedWrapper.Invoke(this, new object[] { 1 });
        }
In the space I was taking to emit the byte code for the same, I could probably vomit all the practical variations of GenericWrapper<> and then take another page or so to go up to, like, 16 arguments and wash my hands of it.

Boz0r
Sep 7, 2006
The Rocketship in action.
We're making a central service hub web api that receives all calls and sends the call to another appropriate web api that interacts with a single system, so all communication goes through that central hub and noone else may contact the other web apis. I'm rewriting a bunch of applications to use this architecture and I've found myself writing a bunch of duplicate code. When I have an application that needs something from a given system, I have to declare a method in 6 different classes and generate 2 new proxies, and that's pretty tedious. I made a pretty drawing:

code:
-------------------
Application	   |
-------------------
	|
	V
SubjectProxy			Auto generated swaggergen proxy
	|
	V
-------------------
SubjectController  |
	|          |
	V	   |	Central Service Hub, has several subjects
ISubjectManager    |
SubjectManager     |
-------------------
	|
	V
SubjectProxy			Auto generated swaggergen proxy
	|
	V
-------------------	
SubjectController  |
	|	   |
	V	   |	
ISubjectManager	   |	Service for this subjects
SubjectManager	   |
	|          |
	V	   |
DAL or something   |	
-------------------
Sometimes there has to be applied some form of logic in the central hub, but most of the time the call just passes right through. How do I avoid writing so much duplicate code?

Boz0r fucked around with this message at 20:52 on Feb 23, 2020

adaz
Mar 7, 2009

Boz0r posted:

We're making a central service hub web api that receives all calls and sends the call to another appropriate web api that interacts with a single system, so all communication goes through that central hub and noone else may contact the other web apis. I'm rewriting a bunch of applications to use this architecture and I've found myself writing a bunch of duplicate code. When I have an application that needs something from a given system, I have to declare a method in 6 different classes and generate 2 new proxies, and that's pretty tedious. I made a pretty drawing:

code:
-------------------
Application	   |
-------------------
	|
	V
SubjectProxy			Auto generated swaggergen proxy
	|
	V
-------------------
SubjectController  |
	|          |
	V	   |	Central Service Hub, has several subjects
ISubjectManager    |
SubjectManager     |
-------------------
	|
	V
SubjectProxy			Auto generated swaggergen proxy
	|
	V
-------------------	
SubjectController  |
	|	   |
	V	   |	
ISubjectManager	   |	Service for this subjects
SubjectManager	   |
	|          |
	V	   |
DAL or something   |	
-------------------
Sometimes there has to be applied some form of logic in the central hub, but most of the time the call just passes right through. How do I avoid writing so much duplicate code?

Does the central service hub do anything other than route the call? Like does it handle any actual business or authentication logic?

Adbot
ADBOT LOVES YOU

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Boz0r posted:

We're making a central service hub web api that receives all calls and sends the call to another appropriate web api that interacts with a single system, so all communication goes through that central hub and noone else may contact the other web apis. I'm rewriting a bunch of applications to use this architecture and I've found myself writing a bunch of duplicate code. When I have an application that needs something from a given system, I have to declare a method in 6 different classes and generate 2 new proxies, and that's pretty tedious. I made a pretty drawing:

code:
-------------------
Application	   |
-------------------
	|
	V
SubjectProxy			Auto generated swaggergen proxy
	|
	V
-------------------
SubjectController  |
	|          |
	V	   |	Central Service Hub, has several subjects
ISubjectManager    |
SubjectManager     |
-------------------
	|
	V
SubjectProxy			Auto generated swaggergen proxy
	|
	V
-------------------	
SubjectController  |
	|	   |
	V	   |	
ISubjectManager	   |	Service for this subjects
SubjectManager	   |
	|          |
	V	   |
DAL or something   |	
-------------------
Sometimes there has to be applied some form of logic in the central hub, but most of the time the call just passes right through. How do I avoid writing so much duplicate code?

That's a really awful idea. You're basically creating a single point of failure in an architecture that's not supposed to have single points of failure.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply