How can I add functionality to COM object in c#? - c#

I am new to COM and c# and I would like to add functionality to a COM object that is exposed by a third-party program.
Initially my intention was to inherit from the COM object class, but I found out it was not so straight forward (for example here).
Presently, I have two interfaces (namely IComAuto and ComAuto) and an associated class (ComAutoClass).
To add my custom methods to ComAuto objects, I have created a class ComObjectWrapper that inherits from this interface and implements it by storing a ComAuto object in a private field.
class ComObjectWrapper : ComAuto
{
private readonly ComAuto ComObj;
public ComObjectWrapper() : base()
{
ComObj = new ComAuto();
}
public short method1(object param)
{
return ComObj.method1(param);
}
...
}
I have a feeling this is not the best way to do this as I need to redirect any call to an original method to the internal ComAuto object.
I tried alternatively to inherit from ComAutoClass directly by setting the Embed Interop types property to false in VS2015. This led some method to return values as object when the code I have already written expects string. I would therefore have to go through all the written code to add some casts to string. Not ideal and moreover I don't have a full understanding of what Embed Interop types is.
I would appreciate if anyone could shed some light on this or point to some useful article (what I have found so far on MSDN sounds a bit cryptic for a beginner like me).

Sounds like a perfect use case for extension methods:
public static class ComAutoExtensions
{
public static short Method1( this ComAuto com, object param )
{
return com.GetShortValue( param );
}
}

Related

Not sure how to properly do this

Ok, so working on a dotnet Core 2 console app that I'm designing to run either on Windows or *Nix. Now the the part I'm trying to figure out is I want to only have one code base and let the code determine if it's running on Win then go one path, or if on *Nix go another path.
So what I'm thinking is create an Interface with the way I want the classes for the two paths to look as far as properties and methods, then create a Win and Nix class implementing the interface.
Seems straightforward, but what I am racking my brain on is how exactly do I create the object based on the OS? I have wrapper code for "IsWindows" and "IsNix" that returns a boolean each, so my thought is to use a If statement to do this. Not sure how to create a generic global variable, then instantiate it in the conditional statement.
Maybe I'm off my rocker and trying to do something odd here, if I am I'm not afraid to be told that. My only other thought is to perform the work inside the conditional statement, but that really would negate my desire to create the object in the conditional based on the OS, then call the same code going forward, using the classes that implement the Interface to make the different code calls as appropriate.
So I feel like a complete idiot with brain lock. Simply creating an object of the type of the Interface is all I needed to do, then set it to an instance of the class in the conditional statement. Easy peasy, not sure why I had a brain fart on that one.
Having common interface and two classes implementing it for different OS'es is definitelly good approach. So let's assume you have
public interface IMyInterface
{
void DoSomething();
}
public class WinClass: IMyInterface
{
public void DoSomething()
{
//Implementation of DoSomething for Windows
}
}
public class NixClass : IMyInterface
{
public void DoSomething()
{
//Implementation of DoSomething for *nix
}
}
Common way to instantiate different implementations of interface (or abstract class) based on certain conditions is using Factory pattern. This might look like this:
public static class MyInterfaceFactory
{
public static IMyInterface CreateMyInterface()
{
if (IsWindows)
return new WinClass();
else if (IsNix)
return new NixClass();
else
throw new PlatformNotSupportedException();
}
}
This is the only platform-dependent part of your code, rest of your code will use only IMyInterface and will be platform independent. You can either use this factory whenever you need to create new instance implementing IMyInterface, or you can use Singleton pattern to ensure, that only one objects will be created for entire application:
public static class MyInterfaceSingleton
{
static MyInterfaceSingleton()
{
Instance = MyInterfaceFactory.CreateMyInterface();
}
public static IMyInterface Instance { get; private set; }
// In C# 7, you can use just this instead:
// public static IMyInterface Instance { get; } = MyInterfaceFactory.CreateMyInterface();
}
Your application then simply call MyInterfaceSingleton.Instance.DoSomething(); whenever needed, in a platform independent way.

Hook to object instantiation

I'm wondering if there's a way to hook to an event whenever an object is instantiated.
If it doesn't, is there a way to retrieve the object to which an attribute is attached to when the attribute is instantiated?
What I want to do is give some of my classes a custom attribute and whenever a class with this attribute is instantiated, run some code for it.
Of course, I could simply place the code in each of those classes' constructor but that's a lot of copy and pasting and I could easily forget to copy that code into one or two classes. And of course, would be very convenient for end users as all they would have to do is add my attribute to their classes and not worry about remember to add that bit of code in their constructors.
I actually can't do a base class because all of those objects already have a base.
Thanks in advance.
Here's an example of what I'd like to do. Either use the attribute's constructor or have an event handler for object instantiation.
public class MySuperAttribute : Attribute
{
public MySuperAttribute()
{
//Something akin to this or the event in Global
Global.AddToList(this.TheTargetObject);
}
}
[MySuperAttribute]
public class MyLabel : System.Windows.Forms.Label
{
}
public static class Global
{
public static void AddToList(Object obj)
{
//Add the object to a list
}
//Some pseudo-hook into the instantiation of any object from the assembly
private void Assembly_ObjectInstantiated(Object obj)
{
if(obj.GetType().GetCustomAttributes(typeof(MySuperAttribute), true).Count != 0)
AddtoList(obj);
}
}
There is no easy way to hook object instantiation externally, maybe with some debugging API, and it has a good reason. It makes your code harder to maintain and understand for other people.
Attributes won't work, because the instance of an attribute is not actually created until it is required - via reflection, and an attribute is assigned to a type, not an instance.
But you may well put the code in a base class, and derive all other classes from it, although it is also not a good practice to pass half-initialized instance to other methods. If the class inherits from ContextBoundObject, you can assign a custom implementation of ProxyAttribute to it and override all operations on it.
If you can't create a common base class (when your types inherit from different types), you can always create the instance with a custom method like this one:
public static T Create<T>() where T : new()
{
var inst = new T();
Global.AddToList(inst);
return inst;
}
However, seeing as you inherit from form controls, their instantiation is probably controlled by the designer. I am afraid there is no perfect solution, in this case.

Using a public method of derived class that is not in interface definition

New to OOP here. I have defined an interface with one method, and in my derived class I defined another public method. My client code is conditionally instantiating a class of the interface type, and of course the compiler doesn't know about the method in one of the derived classes as it is not part of the underlying interface definition. Here is what I am talking about:
public interface IFileLoader
{
public bool Load();
}
public class FileLoaderA : IFileLoader
{
public bool Load();
//implementation
public void SetStatus(FileLoadStatus status)
{
//implementation
}
}
public class FileLoaderB : IFileLoader
{
public bool Load();
//implementation
//note B does not have a SetStatus method
}
public enum FileLoadStatus
{
Started,
Done,
Error
}
// client code
IFileLoader loader;
if (Config.UseMethodA)
{
loader = new FileLoaderA();
}
else
{
loader = new FileLoaderB();
}
//does not know about this method
loader.SetStatus (FileStatus.Done);
I guess I have two questions:
What should I be doing to find out if the object created at run-time has the method I am trying to use? Or is my approach wrong?
I know people talk of IOC/DI all the time. Being new OOP, what is the advantage of using an IOC in order to say, "when my app asks
for an IFileLoader type, use concrete class x", as opposed to simply
using an App.Config file to get the setting?
Referring to your two questions and your other post I'd recommend the following:
What should I be doing to find out if the object created at run-time has the method I am trying to use? Or is my approach wrong?
You don't necessarily need to find out the concrete implementation at runtime in your client code. Following this approach you kinda foil the crucial purpose of an interface. Hence it's rather useful to just naïvely use the interface and let the concrete logic behind decide what's to do.
So in your case, if one implementation's just able to load a file - fine. If your other implementation is able to the same and a bit more, that's fine, too. But the client code (in your case your console application) shouldn't care about it and just use Load().
Maybe some code says more than thousand words:
public class ThirdPartyLoader : IFileLoader
{
public bool Load(string fileName)
{
// simply acts as a wrapper around your 3rd party tool
}
}
public class SmartLoader : IFileLoader
{
private readonly ICanSetStatus _statusSetter;
public SmartLoader(ICanSetStatus statusSetter)
{
_statusSetter = statusSetter;
}
public bool Load(string fileName)
{
_statusSetter.SetStatus(FileStatus.Started);
// do whatever's necessary to load the file ;)
_statusSetter.SetStatus(FileStatus.Done);
}
}
Note that the SmartLoader does a bit more. But as a matter of separation of concerns its purpose is the loading part. The setting of a status is another class' task:
public interface ICanSetStatus
{
void SetStatus(FileStatus fileStatus);
// maybe add a second parameter with information about the file, so that an
// implementation of this interface knows everything that's needed
}
public class StatusSetter : ICanSetStatus
{
public void SetStatus(FileStatus fileStatus)
{
// do whatever's necessary...
}
}
Finally your client code could look something like the follwing:
static void Main(string[] args)
{
bool useThirdPartyLoader = GetInfoFromConfig();
IFileLoader loader = FileLoaderFactory.Create(useThirdPartyLoader);
var files = GetFilesFromSomewhere();
ProcessFiles(loader, files);
}
public static class FileLoaderFactory
{
public static IFileLoader Create(bool useThirdPartyLoader)
{
if (useThirdPartyLoader)
{
return new ThirdPartyLoader();
}
return new SmartLoader(new StatusSetter());
}
}
Note that this is just one possible way to do what you're looking for without having the necessity to determine IFileLoader's concrete implementation at runtime. There maybe other more elegant ways, which furthermore leads me to your next question.
I know people talk of IOC/DI all the time. Being new OOP, what is the advantage of using an IOC [...], as opposed to simply using an App.Config file to get the setting?
First of all separating of classes' responsibility is always a good idea especially if you want to painlessly unittest your classes. Interfaces are your friends in these moments as you can easily substitute or "mock" instances by e.g. utilizing NSubstitute. Moreover, small classes are generally more easily maintainable.
The attempt above already relies on some sort of inversion of control. The main-method knows barely anything about how to instantiate a Loader (although the factory could do the config lookup as well. Then main wouldn't know anything, it would just use the instance).
Broadly speaking: Instead of writing the boilerplate factory instantiation code, you could use a DI-Framework like Ninject or maybe Castle Windsor which enables you to put the binding logic into configuration files which might best fit your needs.
To make a long story short: You could simply use a boolean appSetting in your app.config that tells your code which implementation to use. But you could use a DI-Framework instead and make use of its features to easily instantiate other classes as well. It may be a bit oversized for this case, but it's definitely worth a look!
Use something like:
if((loader as FileLoaderA) != null)
{
((FileLoaderA)loader).SetStatus(FileStatus.Done);
}
else
{
// Do something with it as FileLoaderB type
}
IoC is normally used in situations where your class depends on another class that needs to be setup first, the IoC container can instantiate/setup an instance of that class for your class to use and inject it into your class usually via the constructor. It then hands you an instance of your class that is setup and ready to go.
EDIT:
I was just trying to keep the code concise and easy to follow. I agree that this is not the most efficient form for this code (it actually performs the cast twice).
For the purpose of determining if a particular cast is valid Microsoft suggests using the following form:
var loaderA = loader as FileLoaderA;
if(loaderA != null)
{
loaderA.SetStatus(FileStatus.Done);
// Do any remaining FileLoaderA stuff
return;
}
var loaderB = loader as FileLoaderB
if(loaderB != null)
{
// Do FileLoaderB stuff
return;
}
I do not agree with using is in the if. The is keyword was designed to determine if an object was instantiated from a class that implements a particular interface, rather than if a cast is viable. I have found it does not always return the expected result (especially if a class implements multiple interfaces through direct implementation or inheritance of a base class).

Class hierarchy in C#: how to do it correctly? ('friend' keyword wanted)

I have a class:
public class MyClass {
private List<string> folderList;
// .... a lot of useful public methods here.....
}
Everything is fine. The list of folders is encapsulated, the class is accessible through public methods. OK. Now I need an "options" form that allows a user to choose folders for MyClass. There is a catch: new Setup class must have access to private folderList field (or I have to provide public methods to get and set the folder list - it's essentially the same). In old good C++ I would use 'friend' feature because nobody but Setup class may access folderList. But there is no 'friend' feature in C# (I'm a newbie in the C# world).
P.S. Actually I just made folderList public, but I feel there is a better solution.
Thanks.
You can use "internal" keyword to make your method available only within your assembly/project and if you want to access your internal methods in other project or assembly then you can use "InternalsVisibleTo" attribute, where you can access your internals only in that assembly for which you define this attribute.
MSDN Internal Keyword
I believe the keyword you're looking for is internal. It is loosely equivilent to C++'s friend.
Internal provides assembly-level visibility.
Paired with Femaref's suggestion of using a Property, and you should have your full solution.
I am not sure if this is what he/she wanted. He/she did not put the requirement that the potential client will be in current assembly... Accordingly, when using friend in c++ (which was never considered a good style) you must know the exact type of the class which will be entitled to access the member. If this class is not part of the program you are writing, you cannot grant access this way.
If you want conditional access to some property or method of an instance of a class, you will need to implement some kind of entitlement mechanism, for example:
public IList<Folder> GetFolderList(Object pClient, IEntitlementService pService) {
if (pService.IsEntitledToAccess(this, pClient) {
return folderList;
} else {
throw new AccessNotGrantedException("...");
}
}
I believe there are built-in utilities in the .Net framwork for that purpose, just go and google (or bing)...
As an exact answer to the question I would suggest the following - create a separate interface IFolderList:
interface IFolderList
{
IList<string> FolderList { get; }
...
}
Well, you can add other required members to interface
In the class MyClass implement this interface explicitly.
As a result, the class Setup can gain access to data through an explicit cast to an interface IFolderList or work only with these interface.
An alternative to making an internal method to be used by your Setup class would be to use the Visitor pattern and add a method that takes a Setup class instance as a parameter, then uses the private folderList to initialize/change Setup state as required. Of course that would require the appropriate public methods on the Setup class, so might not fit your needs.
Making folderList field public is the worst case. Exposing implementation details through public fields or through poorly designed public property (there are no differences for collections between public fields and public property with getter and setter).
With public fields you can't promote a field to be a property when you want to add validation, change notification, put it into an interface or change your collection type from one type to another.
BTW, Jeffrey Richter in annotation to Framework Design Guideline mentioned that "Personally, I always make my fields private. I don't even expose fields as internal, because doing so would give me no protection from code in my own assembly"
I think the best way to add explicit interface that expose strict abstraction to MyClass clients.
For example, you may add two separate methods to retrieving folders and to adding new folder to this storage:
class MyClass {
//You should return IList<string>
public IList<string> MyList {get {return myList;} }
//Or even IEnumerable<string>, because you should return
//as minimal interface as your clients needs
public IEnumerable<string> MyList {get {return myList;} }
//You may expose this functionality through internal
//method, or through protected internal method,
//but you should avoid direct access to your implementation
//even for descendants or another classes in your assembly
public void AddElement(string s) {myList.Add(s);}
private List<string> myList;
}
That's what properties are for in C#:
public class MyClass
{
private List folderList;
public List FolderList
{
get {return folderList;}
set {folderList = value;}
}
}
Properties encapsulate the private fields, provide possibilites for validation while setting. Also, you should read up on Generics (abit like templates in c++) and use List<T> instead of List to have a strongly typed collection.
However, you probably wont be able to achieve what you plan unless Setup derives from MyClass. In that case, you can use a protected field.

Modify C# Class method during execution

I'd like to override a class method without inheriting the base class because it'd take a lot of time and modifications and, therefore, more and more tests. It's like this:
class TestClass{
public void initialMethod(){
...
}
}
And somewhere on the code, I'd like to do something like this:
public testMethod()
{
return;
}
test(){
changeMethod(TestClass.initialMethod, testMethod);
}
And this changeMethod function would override the TestClass initialMethod so that it'd call testMethod instead.
Inheriting and overriding the method using normal practices is not an option, as this class A is a graphic component and, inhereting it (and changing it) would break lots of code.
Edit: We don't have the base code for the TestClass, so it's not an option to modify the code there defining the initialMethod as a delegate.
Edit 2: Since this is a graphical component, the designer added a lot of code automatically. If I were to inherit this code, I would have to replace all code added by the designer. That's why I wouldn't like to replace this component.
You need the Strategy pattern.
Main steps:
Create an interface with ie. Do() signature
Your initialMethod() should call a strategy.Do(), where strategy is type of your interface
Create a class that implements this interface. Do() is your testmethod now.
Inject into your main class an instance of this class
If the job it's not so big (let's say just a color replacement or something) then I agree with Jhonny D. Cano's solution with C# (anonymous)delegates.
Edit (after edit 2)
May - just as proof-of-concept - you should inherit the class and replace all references from base class to this new. Do this, and nothing else. If it works, you can think about the next steps (new methods or delegates etc.)
You need only a new checkout from your version control system, and if it maybe fails you can abandon it. It's worth trying.
Perhaps you can do it as a delegate.
class TestClass {
public Action myAction;
public void initialMethod(){
...
}
initialMethod
public TestClass() {
myAction = initialMethod;
}
}
and then on TestMethod
public testMethod()
{
return;
}
test() {
testClassInstance.myAction = testMethod;
}
I think your best bet might be to use a AOP framework like LinFu. There's a codeproject article explaining it:
Introducing LinFu, Part VI: LinFu.AOP – Pervasive Method Interception and Replacement for Sealed Types in Any .NET Language
If 'TestClass' is something you defined, you could replace the 'initialMethod' definition with a property and delegate which can then be set to any method with a given signature. (Even anonymous ones.)
class TestClass {
Action _myMethod;
Action MyMethod {
get { return _myMethod; }
set { _myMethod = value; }
}
var tc = new TestClass()
tc.MyMethod = () -> Console.WriteLine("Hello World!");
tc.MyMethod()
The above code is untested.
The short and simple answer is: if you can't adjust the base TestClass code, no, there's no way you can modify the class to replace a method by another. Once we started doing stuff like that, we'd be in a completely different kind of language, like JavaScript.
The longer answer is: it depends on who is calling the replaced method.
If it's other classes, see if you can't implement a Proxy in between them and the unmodifiable concrete class. Whether this is doable depends on whether that class implements interfaces, or is its own interface.
If it's the class itself, then your only option is to decompile and modify the class, at design time using Reflector (or equivalent tools), or at runtime using Reflection.Emit. However, you'd have to be hurting pretty badly to go this route, as it's sure to be painful and brittle.
Unfortunately you still haven't explained what you are trying do and why. Replacing methods on the go is powerful stuff in the languages that permit it directly... There might be mocking libraries that can be twisted sufficiently far to do the reflection stuff, but then you'd be skating on thin ice.
If you don't have the code use Extension Methods.
public void doSmth(this objectYOUWANT arg)
{
//Do Something
}
Here you use the principle Closed for Modification Open for Extension.
This will add functionality to the library you don't have the source code. It's very clean to do it this way.
Edition:
In FrameWork 3.5 there is something new called Extension Methods. These kind of methods adds functionality to a closed Assembly letting you Extend in functionality a closed dll/assembly.
To use this for example you have a dll that you import, that is called Graphics.dll (you have the reference on your project)
First of all you shoud create a new static class called for example Extension:
public static class Extensions
{
}
Second, you want to add extra functionality to a class contained in Graphics.dll named ChartGraph. You will do this:
public static class Extensions
{
public static void draw(this ChartGraph g)
{
// DO SOMETHING
}
}
Third, when you instantiate a new object from the graphics.dll you now will have the new method you have created:
ChartGraph myG = new ChartGraph();
myG.draw();
As you can see there you have added new functionality without much effort without recompiling the dll, this is good if you don't have the source code.

Categories