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
C# Open File with Default Application and Parameters
Question Mark and Colon in Statement. What Does It Mean
Differencebetween Getter-Only Auto Properties and Expression Body Properties
What Interfaces Do All Arrays Implement in C#
Is There a Generic Constraint I Could Use for the + Operator
How to Have an Enum Bound Combobox with Custom String Formatting for Enum Values
Best Way to Call a JSON Webservice from a .Net Console
Does the Use of the "Async" Suffix in a Method Name Depend on Whether the 'Async' Modifier Is Used
Getting Day Suffix When Using Datetime.Tostring()
Connect to Network Drive with User Name and Password
Is It Necessary to Manually Close and Dispose of SQLdatareader
Cannot Access a Disposed Object in ASP.NET Core When Injecting Dbcontext
How to Convert Ticks to a Date Format
Is Inaccessible Due to Its Protection Level
Could Not Load File or Assembly ... the Parameter Is Incorrect