Best Way to Access Com Objects from C#

Best way to access COM objects from C#

If the library is already registered, you can perform the following steps to have Visual Studio generate an interop assembly for you:

  • Open to your Visual Studio project.
  • Right click on 'References' (right under the project in your Solution Explorer) and select 'Add Reference'.
  • Select the COM tab. (If you don't see this, you have a project type that doesn't support COM.)
  • Select the Component you wish to interop with.
  • Select 'ok'.

This will be a class or set of C# classes that wrap all of the COM interface stuff with a normal C# class. Then you just use it like any other C# library. If the import of the reference worked well, you can explore it like any other reference and the methods/structs/classes/constants should show up in that namespace and intellisense.

This will get you started, at least. If this is deployed in a corporate environment or one you can control, this may be all you need.

Accessing Powershell COM Object in C#?

You can directly mirror what PowerShell does by using dynamic, and creating the instance by ProgId. See https://stackoverflow.com/a/3251325/8446 for example.

accessing object from another method c#

The best way is to just return the actual type you're dealing with from the method


But if that's not an option, and you really are stuck with just object being returned from your method, you have a few options.

If you know the right type, casting would be the simplest way:

((ActualType)x).SomeProperty;

Or to test that the cast is correct:

string val;
if (x is ActualType)
val = (x as ActualType).SomeProperty;

Or, if you know the property name, but not the type of x, then:

PropertyInfo pi = x.GetType().GetProperty("SomeProperty");
string somePropertyValue = (string)pi.GetValue(x, null);

Or, if you're using C# 4, you could use dynamic

string somePropertyValue = ((dynamic)x).SomeProperty;

Just don't go crazy with dynamic. If you find yourself using dynamic excessively, there may be some deeper issues with your code.

More elegant or efficient way to access object properties?

The fundamental difference between C# and JavaScript is that C# is a strongly-typed language. In your main method you did not "add a property", you set the value of an existing property. The reason you're having so much trouble is that your reference variable is not of the correct type.

A type is a collection of properties and methods (a blueprint) for an object instance. This is similar to JavaScript except that in JavaScript you can add properties and methods at run-time and in C# you cannot, you are limited to what is available when the code is written (except for ExpandoObject which is a more advanced concept). The compiler will only let you access the properties and methods that are defined by the type of the variable being used to make that reference. When you return object from your method you are saying "the caller of this method can only access the properties and methods of an object".

So basically you need to decide what properties and methods you want the consumer to be able to access (i.e. the type). In this case your method creates an instance of ResultsObj and returns it, so the return type should be defined as ResultsObj.

public static ResultsObj doResults()
{
ResultsObj newResults = new ResultsObj();
newResults.resultsString = "Here is my string";

return newResults;
}

Now your calling code knows that what is it getting back is a ResultsObj can can access the properties and methods of that type.

ResultsObj secondObj = doResults();
Console.WriteLine(secondObj.resultsString);

It all comes down to types. To reiterate, the compiler is only going to let you access properties and methods of the type defined by the reference variable.

BTW, you could also write the second block of code as:

var secondObj = doResults();
Console.WriteLine(secondObj.resultsString);

This may seem confusing, especially coming from a JavaScript background where var means something different. In this case C# is doing implicit typing. Because the method doResults() is defined as returning a ResultsObj the variable secondObj is implicitly typed as such. If you tried to write the following code it would not compile because the implicit typing already decided that secondObj was a ResultObj and you cannot assign a number to a variable of type ResultsObj.

var secondObj = doResults();
secondObj = 1; // This would cause a compiler error

Propaer way to access object received in Request.Form[]

You can set string Data in below format in Jquery

var formData = new FormData();

        var obj = {
Username: "user5",
Email: "em@example.com"
};

formData.set("data", obj);

and Receive it on Controller side as below format

VB.Net

Dim objUser As cls_User = JsonConvert.DeserializeObject(Of cls_User )(Request("obj"))

C#

cls_User objUser = JsonConvert.DeserializeObject<cls_User>(Request("obj"));

You need to create a class to capture the data coming from FormData() and then use the same object to retrieve it from (Request("obj") to Dim objUser As cls_User

Best way to store and access List of Objects in Controller

You can use the MemoryCache to store things. The below example would store the users for an hour in cache. If you needed to store it on a per user basis you could change it slightly so that the cache key ("Users" in the below example) is generated using the users ID or something.

MemoryCache cache = MemoryCache.Default;
string baseCacheKey = "Users";

public void DoSomethingWithUsers(int userId)
{
var cacheKey = baseCacheKey + userId.ToString();
if (!cache.Contains(cacheKey))
{
RefreshUserCache(userId);
}
var users = cache.Get(cacheKey) as List<User>

// You can do something with the users here
}

public static RefreshUserCache(int userId)
{
var users = ws.SelectUsers();

var cacheItemPolicy = new CacheItemPolicy();
cacheItemPolicy.AbsoluteExpiration = DateTime.Now.AddHours(1);
var cacheKey = baseCacheKey + userId.ToString();
cache.Add(cacheKey, users , cacheItemPolicy);
}

Edit: I've included the option for a userId if you do want to do it per user

Global access to an object from anywhere

As I mentioned in my comment, this looks like an XY Problem. Instead of actually doing global variables, which most people on stack overflow feel are a no-no, I believe the correct solution is to just use IoC/DI. I prefer to use Autofac(no affiliation and there are plenty of DI frameworks to choose from). This allows each object to simply request (by constructor injection or the not recommended approach of property injection) the objects it needs to use in order to function properly. This decreases coupling and can help with testing code (unit tests).

using System;
using Autofac;

public class Program
{
public static void Main()
{
// Start configuring DI
IoCConfig.Start();

// Start "scope" in which Autofac builds objects "in"
using(var scope = IoCConfig.Container.BeginLifetimeScope())
{
// Resolve the Worker
// Autofac takes care of the constructing of the object
// and it's required parameters
var worker = scope.Resolve<Worker>();

worker.DoWork();
}
}
}

// the class that does work, it needs the Configuration information
// so it is added to the constructor parameters
public class Worker
{
private readonly string _connectionString;

public Worker(IConfiguration config)
{
_connectionString = config.ConnectionString;
}

public void DoWork()
{
// Connect to DB and do stuff
Console.WriteLine(_connectionString);
}
}

public static class IoCConfig
{
public static IContainer Container { get; private set; }

public static void Start()
{
var builder = new ContainerBuilder();

// Register Global Configuration
builder.Register(c => new Configuration{
ConnectionString = "my connection string" // or ConfigurationManager.ConnnectionString["MyDb"].ConnectionString;
})
.As<IConfiguration>();

// Register an concrete type for autofac to instantiate
builder.RegisterType<Worker>();

Container = builder.Build();
}

private class Configuration : IConfiguration
{
public string ConnectionString { get; set; }
}

}

public interface IConfiguration
{
string ConnectionString { get; }
}


Related Topics



Leave a reply



Submit