Sharing generic code between UWP projects - c#

I'm developing an UWP app via C#, that uses IBasicVideoEffect with IDirect3DSurface. As mentioned in documentation, I have created Windows Runtime Component (Universal Windows) project.
But settings of effects are stored in some implementation of IPropertySet (smth like Dictionary<object, object>).
To use high - level operations on this storage, I've introduced IPropertySetExtensions into runtime component, that has for example Get<T>, GetOrDefault<T> methods, which return instance of T (not object) from storage.
Than I realized, that same operations will be needed in main project, but when I changed
internal static class IPropertySetExtensions into public one, I got an error like "winmd components cant contain generic methods".
That's why I duplicated extension class into main project.
How can I avoid this duplicating? Maybe move shared code into NuGet .dll or smth?

Unfortunately, when writing a WinRT Component there are quite a few limitations due to the fact that WinRT Components are usable in C++, C#, VB and JS (yes also JS). The following document covers part of what to watch out for: https://learn.microsoft.com/en-us/windows/uwp/winrt-components/creating-windows-runtime-components-in-csharp-and-visual-basic
In your case, I think creating a "Class Library (Universal Windows)" will solve that problem since you can write C# code as you like without having to watch out for WinRT Component limitations.

Related

Build dynamic user interfaces with Blazor and XML

I've been researching ways to build a Web Client using C# that is Single Page and is generated from XML files.
Essentially, I want to have a service that generates XML files that describe the UI of e.g. forms (not the problem). Those XML files are sent to the client, which in term reads the XML and dynamically creates the layout with all the controls. I had hoped to accomplish this in Blazor WebAssembly (I have also looked at ASP.NET WebForms, MVC and CORE (using DevExpress), but none of those are actually meant for SPA clients).
By comparison: We have an Android app that basically does this, similar to what is described right here: https://developer.ibm.com/tutorials/x-andddyntut/
But this time I am not developing an Android app in Java, this is supposed to be a WebClient. And as most coders in the company have a VB.NET background, my head of department would like for it to use C#. But I have tried finding ways to do something like this and have met lots of dead ends, as usually Blazor appears to be used with static pages from design time. I haven't managed to get it to run with RenderFragments, for example.
Any pointers with this would be very much appreciated!
Sincerely,
MR
You can generate the UI dynamycally using RenderTreeBuilder but most of its behavior is intended for internal use (take RenderTreeFrame for example) and therefore I don't think it is a good idea.
In short, I don't believe what you want to achieve is possible.
If these XMLs don't change often, I would think to create a transpiler that converts these XMLs to Blazor code and then recompile the app.
Not a direct answer to creating Forms dynamically, but a suggested alternative method.
For my application I have a number of services which have different properties but are based on underlying common base class. The services defined in several .NET Standard library for each type. The services are things like VoIP, Broadband, FTTC, Ethernet, Router Orders etc. etc. - not much in common, and very different types of data and behaviours.
The base service class has an abstract method called GetView which returns a C# type which is a Razor Component type. Remember in Blazor all those components are just C# classes. The type returned is a Razor Component in the same library (so we have UI as well as business and entity logic encapsulation).
The parent site loads a specific type of service, calls GetView and binds the service to the resulting Component.
That's pretty complicated to describe but I did a proof-of-concept application for this approach in the early days of Blazor as I realised it was going to be capable of this approach: https://github.com/conficient/BlazorDynamicList
There is also a demo site at https://blazordynamiclist.azurewebsites.net/
I won't explain it all in detail here but it follows a similar approach. There is an abstract base class ProductBase that has an abstract method GetViewComponent. Each product can return its preferred Razor Component to display itself.
The 'magic' is the DynamicComponent.cs which is a Razor Component with a BuildRenderTree method that creates a bound instance of the product's component view.

IUnknown on Xamarin/Mono, GetObjectForIUnknown throws PlatformNotSupportedException

I have unmanaged C++ classes, that implement IUnknown properly. I compile the code to a shared library and deploy the library to be used on Android phone. I implemented a simple Xamarin.Forms (C#) application, which uses this library via the standard P/Invoke. Using a factory method, I create a set of these classes, each of its own specific type (and implementing its own interface as well, thus returning S_OK to QueryInterface call with supported iid).
The object gets created using P/Invoked native factory method, so I obtain a valid IntPtr-typed pointer.
However, when I try to call
IntPtr myObj = NativeBridge.CreateMyObject();
var obj = Marshal.GetObjectForIUnknown(myObj);
the code throws PlatformNotSupportedException.
The site https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.getobjectforiunknown?view=netstandard-2.0 states, that this method is supported on .NET Standard 2.0, which I use.
My Xamarin.Forms project is compiled as Xamarin.Android + Shared .NET Standard 2.0 Library, in MS Visual Studio 2017.
Are there some implications I missed? Is GetObjectForIUnknown truly not supported on Xamarin in this configuration? Are there any alternatives to accomplish the same/similar results? Or am I doing something completely wrong on the C# side?
EDIT1: the Marshal.QueryInterface call on the same IntPtr throws NotImplementedException
EDIT2: seems not supported in Mono in master: https://github.com/mono/mono/blob/master/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs - the QueryInterface and GetObjectForIUnknown method implementations are wrapped in conditionals for MOBILE.
So my question is: is there any way I can use COM model on Mono/Android within Xamarin.Forms, without rolling my own native library that bridges the implementations?

COM export method from object in .exe application [duplicate]

I currently have a .NET class library written in C# that exposes its functionaility via COM to a C++ program (pre-.NET).
We now want to move the library out-of-process to free up address space in the main application (it is an image-processing application, and large images eat up address space). I remember from my VB6 days that one could create an "OLE automation server". The OS would automatically start and stop the server .exe as objects were created/destroyed. This looks like the perfect fit for us: as far as I can see nothing would change in the client except it would call CoCreateInstance with CLSCTX_LOCAL_SERVER instead of CLSCTX_INPROC_SERVER.
How would I create such an out-of-process server in C#? Either there is no information online about it, or my terminology is off/out of date!
You can actually do this in .NET (I've done it before as a proof-of-concept), but it's a bit of work to get everything working right (process lifetime, registration, etc).
Create a new Windows application. In the Main method, call RegistrationServices.RegisterTypeForComClients- this is a managed wrapper around CoRegisterClassObject that takes care of the class factory for you. Pass it the Type of the managed ComVisible class (the one you actually want to create- .NET supplies the class factory automatically) along with RegistrationClassContext.LocalServer and RegistrationConnectionType.SingleUse. Now you have a very basic exe that can be registered as a LocalServer32 for COM activation. You'll still have to work out the lifetime of the process (implement refcounts on the managed objects with constructors/finalizers- when you hit zero, call UnregisterTypeForComClients and exit)- you can't let Main exit until all your objects are dead.
The registration isn't too bad: create a ComRegisterFunction attributed method that adds a LocalServer32 key under HKLM\CLSID(yourclsidhere), whose default value is the path to your exe. Run regasm yourexe.exe /codebase /tlb, and you're good to go.
You could always expose your .NET class as COM classes using InteropServices and then configure the library as a COM+ application. The .NET library would run out-of-process and be hosted by a DLLHOST.EXE instance.
Here is an article in MSDN that covers all aspects of how to create COM localserver in c# (.net): link
Your post started a while ago and I had the same problem. The following link is absolute gold and tells you everything
http://www.andymcm.com/blog/2009/10/managed-dcom-server.html

Class object sharing across C# and Android

I create a lot of object classes when I do programming. There are many situations where same object definition will be reused across multiple projects. In windows, I simply build them into .dll file library and include them as the project reference. Therefore, when I need to add additional properties or methods, I just need to do it once and I don't need to worry about go through all projects and manually update the object class definition.
Now, I'm given a project to build an Android application which requires several object classes that's being used within other projects (and must be synced). Of course, I can manually create them within Android and update them every time whenever there's a change, but this is very dangerous because one day in the future, it is very likely to be out-of-synced.
Anyone have suggestions on how to share class library across C# and Android?
Thank you
The only way I know how to do this is to use Xamarin which would allow you to write your entire Android application in C#.
The problem is Android and .Net use completely different runtimes that are not compatible.
I don't have a clear enough view of what your application does, but if you are using the C# objects on a webAPI and looking to keep your objects synced with the client app, you can use Breeze.js - this keeps your client/server biz objects synced. The classes get pulled in dynamically via a meta service call.

Cyclic dependency issue in referencing a window form application and class library

I have a 'window forms application' project and it has a reference to class library lets say LibA. Now LibA wants to access some data of this 'window forms application' project, how to do it now ? I cant add reference of this 'window forms application' project to LibA because of cylic dependency thing.
You can not do both things referring LibA in 'window forms application' and referring 'window forms application' in LibA. You can add reference in one way only.
If you are in such a situation that means your project architecture is not well designed. So to over come this situation you should design it in such a manner so that you don't face this situation.
More over you can refer below link in which Cyclic Dependency and how to over come it has been explained very well
What is Circular dependency and how do we resolve it
A Class library should never reference a Windows Forms (an application level proejct)
The issue you're facing is related to software design (or software architecture)
If the class library needs something from the Windows Forms it means that the windows forms project is doing something it is not responsible for.
You have two solutions and both imply redesign
Pass the code from the windows forms to your class library
or
Create a new class library project, put the 'common' code there and reference it in both projects
I strongly advise you to read about system architecture
SOLID Design
Multitier applications. an example with asp.net
EDIT
Nevertheless, if you are aware of its dangerous, you could reference the windows forms dll itself from the output bin directory instead of the Project. Attention that is very bad code and done only in extremely rare cases.
Second choice, also not recommended, is to use reflection to access the windows forms dll. You can use Assembly.Load() and then invoke or get property values in run-time.
Given your (perhaps) level of expertise i'd strongly maintain the recommendation of learning more about system architecture.
Here's quick and dirty a trick to bypass cyclic dependency issues (nevertheless, I agree with SpiderCode to say that this should not happen with a good architecture).
In your assembly LibA, define:
public interface IMyUi
{
// put whatever functions you need to access from LibA
string GetData();
}
public static class MyUiProvider
{
public static IMyUi MyUi;
}
In your assembly LibB, just make the class you want implement IMyUi, and assign MyUiProvider.MyUi on program load
Once this is done, you can use your UI via MyUiProvider.MyUi.GetData().
NB: I put that as static to have quick example of the pattern. This might not be a good practice: static keeps your UI in gc roots, and it forbids you to have multiple instances... but you can transpose the idea to instance injection of the interface.
NB 2: this pattern is known as "inversion of control"

Categories