Make internal classes accessible to all external assemblies - c#

I'm implementing a modding interface for a game written in .net using Harmony. The original game code consists of mostly classes without specific access modifiers, which unfortunately defaults them to internal and makes modding kind of a pain. I have access to the original source code, so I can modify it however I want.
I'm aware of Friend Assemblies and the ignoreaccesschecksto modifier, but these options don't really lend themselves well to a modding interface.
I believe the correct way to do this is to manually change all the classes to public. Is there a better way to do this/is this a bad idea?

Related

How to hide C# class from custom IL Inspector?

I am currently working with a piece of software known as Kofax TotalAgility or KTA for short.
This is Business Process Automation Software, which I have the "pleasure" of expanding with custom .net libraries.
I have been creating a MS Graph library to perform actions with the MS Graph API. The API works great and I am quite pleased with how it turned out.
However due to the way KTA is accessing methods in classes I have used "Data classes" (dont know if that is the right word) to use as input parameters for my methods. To be clear these methods have no functionality other than to store data for methods to use, the reason I am doing this, is because of the way it is structured in the KTA class inspector (I am assuming that KTA uses the IL Code from my library to create a list of classes and methods).
This is what I am expecting the user is shown when they are using my methods. As you can see by using classes as input parameters I get this nice hierarchical structure.
By using classes as input parameters another issue occurs which is that my "Data Classes" are show in the list of classes, which produces alot of unnecessary clutter.
Is there a way to hide these classes from the inspector? I get that it might be an internal KTA issue, which of course would mean I am not asking in the right place, and it is an internal Kofax issue.
However if there is some C# or .NET way of doing this, that would be preferable.
There are a number of different terms for the data/parameter classes that you mention, such as DTO (data transfer objects), POCO (plain old C# objects), or the one that you can see in the KTA product dlls: model classes.
There is not a direct way to hide public classes from KTA. However, when you use the KTA API via the TotalAgility.Sdk.dll, you notice that you don’t see all of the parameter classes mixed in with the list of the classes that hold the SDK functions. The reason is just that these objects are in a separate referenced assembly: Agility.Sdk.Model.dll. When you are configuring a .NET activity/action in KTA, it will only list the classes directly in the assembly that you specify, not referenced assemblies.
If you are using local assembly references in KTA, then this should work because you can just have your referenced assembly in the same folder as your main dll. However if you are ILMerging into a single dll to can add it to the .NET assembly store, then this approach won’t work.
When ILMerged together, the best you can do is to have your parameter classes grouped in a namespace that helps make it clear. What I do is have a main project with just one class that acts as a wrapper for any functions I want to expose. Then use ILMerge with the internalize option, which changes visibility to internal for any types not in the primary assembly. To allow the model classes to still be public, I keep them in a specific namespace and add that namespace to the exclude list for the internalize command. See Internalizing Assemblies with ILMerge for more detail.
Keep in mind that anyone seeing this list is configuring a function call with your dll. Even if they are not a skilled developer, they should at least have some competence for this type of task (hopefully). So even if the list shows a bunch of model classes, it shouldn’t be too hard to follow instructions if you tell them which class is to be used.

Explicit interface implementation for COM interfaces in C#

Some time I ago I was working on a major refactoring of an old Win32 program implemented with COM, and there were various parts that were implemented with C# (.NET). During my work on this project, I ran across a Microsoft page on COM programming in C# that recommended C# classes explicitly implement COM interfaces, rather than implicity. I recently tried to remember why, and I couldn't. I also couldn't find the page on the MSDN site again. Can anybody please tell me why Microsoft might recommend this ?
Hmm, that makes a wee bit of sense, COM is pure interface-based programming and the actual implementation of the interfaces should be hidden. Implementing interface methods explicitly gets you that automatically because they cannot be public.
Actually doing this is quite pointless, you could (and should) simply apply the [ClassInterface(ClassInterfaceType.None)] attribute to the class. That by itself ensures that the implementation isn't exposed, only the interfaces implemented by the class are visible. Implementing the interface methods explicitly isn't actually good enough. Because you cannot hide the fact that your class inherits System.Object. Which exposes the four public methods of Object and puts a reference to mscorlib.tlb in your type library, a reference that a real COM client will never use. It will almost always work because the odds that the compiler that uses your class runs on a machine that doesn't have .NET installed are pretty small. But very yucky nonetheless, it isn't actually required. Only the machine that uses the class needs it installed.
Just don't do this. Declare the interfaces you implement, give them the [InterfaceType(ComInterfaceType.InterfaceIsDual)] attribute to allow them to be used both early and late bound. And hide the actual implementation of them with [ClassInterface(ClassInterfaceType.None)]. Only sensible way.
It's old, but from here: http://msdn.microsoft.com/en-us/library/aa288461%28v=VS.71%29.aspx they mention implementing an interface explicitly so you can implement multiple interfaces that have the same member names.
This also requires that the user of your class cast an instance of your class to the appropriate interface.
As for why this is especially important for COM: my first guess is so that COM can call one set of methods while managed code may call another. However, I'm guessing here.

Can I expose only a portion of one .NET DLL's public classes via a different "API" DLL?

I am designing a WPF application that uses a DLL with maybe 40 public classes. I need these to be public for a variety of reasons including ease of data binding and obfuscation. I would like to allow other people to use only a portion of these classes as an API for my software.
I thought I would create the main library (core.dll) and an API library (coreAPI.dll) with the API DLL to be referenced in a new project. Is there a way to allow coreAPI.dll to expose only a few of the classes that exist in core.dll? It's not so much a security issue as I primarily want to simply hide some of the unwanted classes from the Visual Studio Intellisense.
Again, internal classes for the ones I want to hide is not really an option because I need to data bind some of these classes in WPF and for that, they must be public. Are there any other ways of doing this?
As Damien already mentioned, if the only thing you'd like to do is to hide from Intellisense you can add the following attribute to your hidden classes:
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
If the primary issue is Intellisense, then moving these classes into a separate namespace would surely do the trick?
Of course, you could split the classes into two separate assemblies. You may have some issues there with having to expose more classes than you want (because they now live in separate assemblies), which might be resolvable using the InternalsVisibleTo attribute

Any way to avoid creating a huge C# COM interface wrapper when only a few methods needed?

Greetings all,
I’m working on a C# program that requires being able to get the index of the hot item in Windows 7 Explorer’s new ItemsView control. Fortunately, Microsoft has provided a way to do this through UI Automation, by querying custom properties of the control.
Unfortunately, the System.Windows.Automation namespace inexplicably does not seem to provide a way to query custom properties! This leaves me with the undesirable position of having to completely ditch the C# Automation namespace and use only the unmanaged COM version. One way to do it would be to put all the Automation code in a separate C++/CLI module and call it from my C# application. However, I would like to avoid this option if possible, as it adds more files to my project, and I’d have to worry about 32/64-bit problems and such.
The other option is to make use of the ComImport attribute to declare the relevant interfaces and do everything through COM-interop. This is what I would like to do. However, the relevant interfaces, such as IUIAutomation and IUIAutomationElement, are FREAKING HUGE. They have hundreds of methods in total, and reference tons and tons of interfaces (which I assume I would have to also declare), almost all of which I will never ever use. I don’t think the UI Automation interfaces are declared in any Type Library either, so I can’t use TLBIMP.
Is there any way I can avoid having to manually translate a bajillion method signatures into C# and instead only declare the ten or so methods I actually need? I see that C# 4.0 added a new “dynamic” type that is supposed to ease COM interop; is that at all relevant to my problem?
Thanks
The most important thing (from the perspective of calling a COM method from C#) is that the methods appear in the interface in the right order. If you're not using a method, you can just declare it as void and nothing bad will happen (unless you actually call it!). This saves you from having to work out the correct signatures and define all the other types, etc. For example,
[ComImport, Guid("30cbe57d-d9d0-452a-ab13-7ac5ac4825ee"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IUIAutomation
{
void CompareElements();
void CompareRuntimeIds();
void GetRootElement();
// 50 or so other methods...
// ... define only the signatures for the ones you actually need
}
The methods should be defined in exactly the same order they appear in UIAutomationClient.h (in the Windows SDK).

C# Class function members declaration & implementation

Is there a concept in C# of class definition and implementation similar to what you find in C++?
I prefer to keep my class definitions simple by removing most, if no every, implementations details (it depends on several factors as you may know, but generally I move towards leaving most member implementation details outside the class definition). This has the benefit of giving me a bird's eye view of the class and its functionality.
However in C# it seems I'm forced to define my member functions at the point of declaration. Can this be avoided, or circumvent some way?
During my apprenticeship of C#, this is one aspect that is bothering me. Classes, especially complex ones, become increasingly harder to read.
This is really a case of needing to step back and see the bigger picture. Visual studio has many, many tools to help you write and manipulate your code, from outlining, #regions, class view, class diagrams, the Code Definition Window and many more.
C# isn't C++, if you try to make it so then you'll trip over yourself and no-one else will be able to read your code.
A day spent learning to use the Visual Studio tools will repay the investment many times over in terms of productivity and you'll soon wonder how you ever lived with that C++ way of doing things.
Update in response to comments
I have long since stopped regarding my code as simple text files. I regard code as an organic thing and I find that allowing myself to rely on a feature-rich IDE lets me move up and down levels of abstraction more easily and enhances my productivity no end. I suppose that could be a personal trait and perhaps it is not for everyone; I have a very 'visual' mind and I work best when I can see things in pictures.
That said, a clever IDE is not an excuse for poor style. There are best practices for writing "clean code" that don't require an smart IDE. One of the principles of clean code is to keep the definition of something near its use and I think that could be extended to cover declaration and definition. Personally, I think that separating the declaration and definition makes the code less clear. If you are finding that you get monster classes that are hard to understand, then that might be a sign that you're violating the Single Responsibility Principle.
The reason for separate definition and declaration in c/C++ is because C++ uses a single pass compiler, where forward references cannot be resolved later, unlike C# and its two-pass compiler which can happily find references regardless of the order of declaration. This difference stems from the different design philosphies of the compilers: C/C++ considers each source file to be a unit of compilation, whereas in C# the entire project is considered to be the unit of compilation. I suppose when you are used to working in the C/C++ way then separating the declaration and definition can appear to be a desirable element of style, but I personally believe that keeping declaration and use (or in this case declaration and definition) enhances, rather then reduces, readability. I used to be a C programmer myself until I started using C# in 2001. I always loved C and thought it's way of doing things was the 'bees knees'. These days when I read C/C++ code I think it looks absolutely horrendous and I can't believe we used to put up with working that way. It's all a matter of what you are used to, I suppose.
If you're using Visual Studio, you can take advantage of the Class View. You can also use the expand/collapse features of the source code editor.
In the improbable case that your tools don't help, you can always write a quick utility that will summarize the class for you.
If the class has been compiled, you can use Reflector to view the class, too.
No, there is no concept of implementation and header files in C# like you find in C/C++. The closest you can come to this is to use an interface, but the interface can only define the public members of your class. You would then end up with a 1-to-1 mapping of classes and interfaces, which really isn't the intent for how interfaces are to be used.
You could get a similar result by defining an interface for each of your classes which they then implement.
It sounds like you're referring to interfaces. In c#, you can define all of your member functions in an interface, and then implement them in another class.
In C# you could fake it with partial classes and partial members to a point, however, forward declarations and prototypes go the way of the dodo bird with your newer languages. Class View, Class Diagrams, Intellisense, et al, all help to remove the potential need for those "features".
Define an interface.
Then it's nice to be able to automatically implement the interface using a nice code assist tool.
If you find that a class is hard to read or difficult to understand, that's often a sign that the class is trying to do too much. Instead of trying to duplicate C++'s separation of declarations and definitions, consider refactoring the troublesome class into several classes so that each class has less responsibility.
Whenever it's possible or desirable, I'll go with the previous responses and define an interface. but it's not always appropriate.
alternatively, you can work around this "problem" by using some static code inspection tools. Resharper's "File Structure" window will give you exactly what you want. you can also use the built in "Class View" from visual studio. but I prefer the former.
The prototyping that I guess you are referring to does not really exist in C#. Defining interfaces as others have suggested will give you a point where you have declarations of your methods collected, but it's not the same thing as prototypes, and I am not so sure that it will help you in making your implementation classes easier to read.
C# is not C++, and should probably not be treated as C++.
Not sure what you mean by your classes continue to grow and become hard to read. Do you mean you want a header file like view of a class's members? If so, like John suggested, can't you just collapse the implementation so you don't have to see it?
If you don't want every class to implement a certain thing, then interfaces are probably the way to go (like others are saying).
But as a side thought, if your classes themselves get more and more complex as a your write the program, perhaps it's more of a design issue than a language problem? I think a class should have one responsibility and not take on more and more responsibilities as the program grows, rather the number of classes and how old classes are used should grow and get more complex as you continue to develop your software?
There are two remedies for this to make it more C++-ish:
Create an interface file that declares all method signatures and properties
Implement that interface in a class across multiple files by using the partial modifier on the class definitions
Edits:
// File: ICppLikeInterface.cs
public interface ICppLikeInterface
{
...
}
// File: CppLikeImplementation1.cs
public partial class CppLikeImplementation : ICppLikeInterface
{
...
}
// File: CppLikeImplementation2.cs
public partial class CppLikeImplementation : ICppLikeInterface
{
...
}
The C++ way of separating interface into a header file is mostly (I think) due to an early design decision when C was created to allow fast, incremental compilations during the "old days", as the compiler throws away any meta data, contrary to Smalltalk. This is not a matter with C# (nor Java) where tens of thousands of lines compiles within seconds on recent hardware (C++ still doesn't)

Categories