NET APIs include classes, interfaces, delegates, and value types that expedite and optimize the development process and provide access to system functionality. To facilitate interoperability between languages, most .NET types are CLS-compliant and can therefore be used from any programming language whose compiler conforms to the common language specification (CLS).
.NET provides a rich set of interfaces, as well as abstract and concrete (non-abstract) classes. You can use the concrete classes as-is or, in many cases, derive your own classes from them. To use the functionality of an interface, you can either create a class that implements the interface or derive a class from one of the .NET classes that implements the interface.
This naming scheme makes it easy for library developers extending .NET to create hierarchical groups of types and name them in a consistent, informative manner. It also allows types to be unambiguously identified by their full name (that is, by their namespace and type name), which prevents type name collisions. Library developers are expected to use the following convention when creating names for their namespaces:
The use of naming patterns to group related types into namespaces is a useful way to build and document class libraries. However, this naming scheme has no effect on visibility, member access, inheritance, security, or binding. A namespace can be partitioned across multiple assemblies and a single assembly can contain types from multiple namespaces. The assembly provides the formal structure for versioning, deployment, security, loading, and visibility in the common language runtime.
The System namespace is the root namespace for fundamental types in .NET. This namespace includes classes that represent the base data types used by all applications, for example, Object (the root of the inheritance hierarchy), Byte, Char, Array, Int32, and String. Many of these types correspond to the primitive data types that your programming language uses. When you write code using .NET types, you can use your language's corresponding keyword when a .NET base data type is expected.
In addition to the base data types, the System namespace contains over 100 classes, ranging from classes that handle exceptions to classes that deal with core runtime concepts, such as application domains and the garbage collector. The System namespace also contains many second-level namespaces.
For more information about namespaces, use the .NET API Browser to browse the .NET Class Library. The API reference documentation provides documentation on each namespace, its types, and each of their members.
Class libraries are the shared library concept for .NET. They enable you to componentize useful functionality into modules that can be used by multiple applications. They can also be used as a means of loading functionality that is not needed or not known at application startup. Class libraries are described using the .NET Assembly file format.
Platform-specific libraries are bound to a single .NET platform (for example, .NET Framework on Windows) and can therefore take significant dependencies on a known execution environment. Such an environment exposes a known set of APIs (.NET and OS APIs) and maintains and exposes expected state (for example, Windows registry).
Developers who create platform-specific libraries can fully exploit the underlying platform. The libraries will only ever run on that given platform, making platform checks or other forms of conditional code unnecessary (modulo single sourcing code for multiple platforms).
Platform-specific libraries have been the primary class library type for the .NET Framework. Even as other .NET implementations emerged, platform-specific libraries remained the dominant library type.
Portable libraries are supported on multiple .NET implementations. They can still take dependencies on a known execution environment, however, the environment is a synthetic one that's generated by the intersection of a set of concrete .NET implementations. Exposed APIs and platform assumptions are a subset of what would be available to a platform-specific library.
You choose a platform configuration when you create a portable library. The platform configuration is the set of platforms that you need to support (for example, .NET Framework 4.5+, Windows Phone 8.0+). The more platforms you opt to support, the fewer APIs and fewer platform assumptions you can make, the lowest common denominator. This characteristic can be confusing at first, since people often think "more is better" but find that more supported platforms results in fewer available APIs.
Many library developers have switched from producing multiple platform-specific libraries from one source (using conditional compilation directives) to portable libraries. There are several approaches for accessing platform-specific functionality within portable libraries, with bait-and-switch being the most widely accepted technique at this point.
.NET Standard libraries are a replacement of the platform-specific and portable libraries concepts. They are platform-specific in the sense that they expose all functionality from the underlying platform (no synthetic platforms or platform intersections). They are portable in the sense that they work on all supporting platforms.
.NET Standard exposes a set of library contracts. .NET implementations must support each contract fully or not at all. Each implementation, therefore, supports a set of .NET Standard contracts. The corollary is that each .NET Standard class library is supported on the platforms that support its contract dependencies.
Class libraries are supported on Mono, including the three types of libraries described previously. Mono is often viewed as a cross-platform implementation of .NET Framework. In part, this is because platform-specific .NET Framework libraries can run on the Mono runtime without modification or recompilation. This characteristic was in place before the creation of portable class libraries, so was an obvious choice to enable binary portability between .NET Framework and Mono (although it only worked in one direction).
I have a compiler for a domain specific language that outputs a .net dll (that can then be used to do whatever the DSL said it should). It works well under .net but now I need to make the compiled dll functionality accessible from Java. The interface changes depending on the DSL, much like it would if I was implementing an F# type provider.
Ideally, I would like something along the lines of Reflection.Emit except that it would generate Java bytecode. It is important that the end-user can debug their Java code that uses my generated library from a Java GUI, so I don't think I can just use IKVM to instead include the Java code in .net. I also cannot use a commercial product such as JNBridge because all the users would need to install it, and call it every time their DSL code changes.
Is there a better solution than generating a .java file in text format and compiling it with a Java compiler? The .java file would just be a light-weight interface talking to the .net dll over some IPC mechanism (perhaps a named pipe), and its purpose would be to provide a typesafe interface similar to what would be seen from a .net application (except with indexers, getters, setters, overloads, etc replaced with some sort of horribly verbose syntax). Many thanks.
If you want to use dlls then you have to use JNI (or something similar or based on JNI like jni4net). It's not as pleasant as say, using c++ from c#, but it's pretty doable and far and away the best way to use dlls from java (I think the second best is re-writing the native code).
Alternatively you could run a windows process alongside your java app and soap/json/namedpipes/etc between the two, is that what you suggest in the last paragraph?This would be odd for a small solution, but for a larger modular project it's not so crazy. I would recommend using sockets to communicate between the two, because I think sockets are easiest. It says client/server in the example, but it could be two processes (java and f#). ... This causes problems for performance, synchronisation, firewalls etc.. ahhh, just use JNI.
The .NET library is developed and supported on GitHub and will be kept up to date with the latest features from OpenAI. Work will continue over the next few months to gather feedback to improve the library and release a stable NuGet package.
OpenAI and the .NET team also thank these project maintainers for their extraordinary efforts in filling a void within the community. Even with the release of the official package from OpenAI, there are opportunities for community libraries to add significant value on top. We look forward to collaborating with the community in this space.
Thank you for the detailed answer. So, to make sure I understand the split here. Previously, we would use an OpenAIClient to communicate with both ChatGPT from OpenAI and Azure OpenAI Service. With different endpoints and settings, of course. But going forward, we will use AzureOpenAIClient from the Azure.AI.OpenAI package to communicate with Azure OpenAI Service and OpenAIAPI from the OpenAI package to communicate with OpenAI?
A quick update on this for anyone interested in making the switch. I migrated my code to the new prerelease of the Azure.AI.OpenAI package. Everything is running great. As already mentioned in this thread, you use AzureOpenAIClient when communicating with a model hosted on Azure and OpenAIClient when communicating with a model on OpenAI. One thing you should be aware of is that the new clients now throw ClientResultException instead of RequestFailedException. So, if you catch an exception to detect an invalid API key or similar, you need to change the catch block.
OpenAI services can be thought of like any other (Azure) AI Service, for which there has never been support in 
ML.NET (other than exporting a custom trained model from services like Custom Vision and running inference using the ONNX APIs in 
ML.NET).
 3a8082e126