Is there any elegant MEF way to list all (property and constructor) imports of a given interface for a given assembly?
I realize I can scan all the exported types with reflection, checking for [Import] or [ImportingConstructor] attributes (and so on), but I think that MEF already knows that.
Elegant is just too subjective, so I hope my solution fits your concept of elegance =)
You can use ReflectionModelServices class, which is at System.ComponentModel.Composition.ReflectionModel. As its name implies it uses Reflection internally, but well, is part of MEF and MEF uses reflection.
When you said without reflection I assume you refer to using reflection directly on the type. So, lets go on...
Let say we have the following:
internal interface IFoo { }
internal class Boo : IFoo
{
[Import] public string SomeString;
[ImportingConstructor]
public Boo(int someInt) { }
}
internal class Moo : IFoo
{
[Import] public float SomeFloat;
}
Then wherever you are creating your catalogs (for me it happened to be in Main of a Console application) you iterate over your catalog's parts and inspect each part's import definitions:
private static void Main(string[] args)
{
var regBuilder = new RegistrationBuilder();
regBuilder.ForTypesMatching(t => typeof(IFoo).IsAssignableFrom(t))
.Export<IFoo>();
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly(), regBuilder);
foreach (var composablePartDefinition in catalog.Parts)
if (typeof(IFoo).IsAssignableFrom(ReflectionModelServices.GetPartType(composablePartDefinition).Value))
foreach (var importDefinition in composablePartDefinition.ImportDefinitions)
Console.WriteLine(
$"Contract name: {importDefinition.ContractName}. Is parameter (for ImportingConstructor stuff): {ReflectionModelServices.IsImportingParameter(importDefinition)}");
Console.ReadLine();
}
The output for this is:
You can try to explore other properties that define ImportDefinition, for example you may want to know the cardinality or the share policy, both of them are there... =)
Hope this helps.
I am getting into C# and I am having this issue:
namespace MyDataLayer
{
namespace Section1
{
public class MyClass
{
public class MyItem
{
public static string Property1{ get; set; }
}
public static MyItem GetItem()
{
MyItem theItem = new MyItem();
theItem.Property1 = "MyValue";
return theItem;
}
}
}
}
I have this code on a UserControl:
using MyDataLayer.Section1;
public class MyClass
{
protected void MyMethod
{
MyClass.MyItem oItem = new MyClass.MyItem();
oItem = MyClass.GetItem();
someLiteral.Text = oItem.Property1;
}
}
Everything works fine, except when I go to access Property1. The intellisense only gives me "Equals, GetHashCode, GetType, and ToString" as options. When I mouse over the oItem.Property1, Visual Studio gives me this explanation:
MemberMyDataLayer.Section1.MyClass.MyItem.Property1.getcannot be accessed with an instance reference, qualify it with a type name instead
I am unsure of what this means, I did some googling but wasn't able to figure it out.
In C#, unlike VB.NET and Java, you can't access static members with instance syntax. You should do:
MyClass.MyItem.Property1
to refer to that property or remove the static modifier from Property1 (which is what you probably want to do). For a conceptual idea about what static is, see my other answer.
You can only access static members using the name of the type.
Therefore, you need to either write,
MyClass.MyItem.Property1
Or (this is probably what you need to do) make Property1 an instance property by removing the static keyword from its definition.
Static properties are shared between all instances of their class, so that they only have one value. The way it's defined now, there is no point in making any instances of your MyItem class.
I had the same issue - although a few years later, some may find a few pointers helpful:
Do not use ‘static’ gratuitously!
Understand what ‘static’ implies in terms of both run-time and compile time semantics (behavior) and syntax.
A static entity will be automatically constructed some time before
its first use.
A static entity has one storage location allocated, and that is
shared by all who access that entity.
A static entity can only be accessed through its type name, not
through an instance of that type.
A static method does not have an implicit ‘this’ argument, as does an
instance method. (And therefore a static method has less execution
overhead – one reason to use them.)
Think about thread safety when using static entities.
Some details on static in MSDN:
Static Classes in C#
Static Constructors in C#
This causes the error:
MyClass aCoolObj = new MyClass();
aCoolObj.MyCoolStaticMethod();
This is the fix:
MyClass.MyCoolStaticMethod();
Explanation:
You can't call a static method from an instance of an object. The whole point of static methods is to not be tied to instances of objects, but instead to persist through all instances of that object, and/or to be used without any instances of the object.
No need to use static in this case as thoroughly explained. You might as well initialise your property without GetItem() method, example of both below:
namespace MyNamespace
{
using System;
public class MyType
{
public string MyProperty { get; set; } = new string();
public static string MyStatic { get; set; } = "I'm static";
}
}
Consuming:
using MyType;
public class Somewhere
{
public void Consuming(){
// through instance of your type
var myObject = new MyType();
var alpha = myObject.MyProperty;
// through your type
var beta = MyType.MyStatic;
}
}
cannot be accessed with an instance reference
It means you're calling a STATIC method and passing it an instance. The easiest solution is to remove Static, eg:
public static void ExportToExcel(IEnumerable data, string sheetName)
{
Remove the static in the function you are trying to call. This fixed the problem for me.
I got here googling for C# compiler error CS0176, through (duplicate) question Static member instance reference issue.
In my case, the error happened because I had a static method and an extension method with the same name. For that, see Static method and extension method with same name.
[May be this should have been a comment. Sorry that I don't have enough reputation yet.]
I know this is an old thread, but I just spent 3 hours trying to figure out what my issue was. I ordinarily know what this error means, but you can run into this in a more subtle way as well. My issue was my client class (the one calling a static method from an instance class) had a property of a different type but named the same as the static method. The error reported by the compiler was the same as reported here, but the issue was basically name collision.
For anyone else getting this error and none of the above helps, try fully qualifying your instance class with the namespace name. ..() so the compiler can see the exact name you mean.
Check whether your code contains a namespace which the right most part matches your static class name.
Given the a static Bar class, defined on namespace Foo, implementing a method Jump or a property, chances are you are receiving compiler error because there is also another namespace ending on Bar. Yep, fishi stuff ;-)
If that's so, it means your using a Using Bar; and a Bar.Jump() call, therefore one of the following solutions should fit your needs:
Fully qualify static class name with according namepace, which result on Foo.Bar.Jump() declaration. You will also need to remove Using Bar; statement
Rename namespace Bar by a diffente name.
In my case, the foollowing compiler error occurred on a EF (Entity Framework) repository project on an Database.SetInitializer() call:
Member 'Database.SetInitializer<MyDatabaseContext>(IDatabaseInitializer<MyDatabaseContext>)' cannot be accessed with an instance reference; qualify it with a type name instead MyProject.ORM
This error arouse when I added a MyProject.ORM.Database namespace, which sufix (Database), as you might noticed, matches Database.SetInitializer class name.
In this, since I have no control on EF's Database static class and I would also like to preserve my custom namespace, I decided fully qualify EF's Database static class with its namepace System.Data.Entity, which resulted on using the following command, which compilation succeed:
System.Data.Entity.Database.SetInitializer<MyDatabaseContext>(MyMigrationStrategy)
Hope it helps
YourClassName.YourStaticFieldName
For your static field would look like:
public class StaticExample
{
public static double Pi = 3.14;
}
From another class, you can access the staic field as follows:
class Program
{
static void Main(string[] args)
{
double radius = 6;
double areaOfCircle = 0;
areaOfCircle = StaticExample.Pi * radius * radius;
Console.WriteLine("Area = "+areaOfCircle);
Console.ReadKey();
}
}
How can I derive from a class through reflection? The following works for getting an existing instance and for creating a new instance of the class.
public class TreeViewSHWinstances {
[MenuItem("Reflect/CreateSHWinstances")]
static void Activate() {
Main();
}
static void Main() {
Assembly asm = typeof(UnityEditor.EditorWindow).Assembly;
Type wndType = asm.GetType ("UnityEditor.SceneHierarchyWindow");
// Grabs an existing instance if it exists and then sets the focus to it.
EditorWindow exstWnd = EditorWindow.GetWindow (wndType);
// Always create a new instance regardless if one already exists.
EditorWindow newWnd = (EditorWindow)Activator.CreateInstance (wndType);
}
}
This is what I actually want to do, but obviously the assembly is not yet loaded and when I have tried to acquire it form the above class I get an error that says it is not a Type even though I'm requesting wndType.
// THIS IS NOT INTENDED TO NOR DOES IT WORK.
public MySceneHierarchyWindow : UnityEditor.SceneHierarchyWindow {
}
My guess was to use Emit in some way, but I after experimenting with it I'm not sure it is the right direction.
I have a class similar to the following
class ObjectCaller
{
public void Process (String NameSpace) {
Type t = Type.GetType(NameSpace + ".Main");
if (t != null)
{
if (t.IsSubclassOf(typeof(Window)))
{
Object obj = Activator.CreateInstance(t);
}
else {
throw new NotAbstractedException();
}
}
else {
throw new MainNotFoundException();
}
}
}
A namespece is passed to the Render() Method of the class and the passed namespace should have a class .Main and also the class should be abstracted from Window class. Which is working fine. But I am unable to do unit test so that if the class Main exists but it is not an abstract class of Window, it should throw an exception.
[TestMethod()]
[ExpectedException(typeof(NotAbstractedException))]
public void MainNotAbstractedTest() {
ObjectCaller oc = new ObjectCaller();
oc.Process("name.space.of.class");
}
I have tried using MOQ to MOCK System.Type classes IsSubClassOf method and with searching have found that its not possible to MOCK static classes. And also I don't want to change ObjectCaller just for the purpose of UnitTesting, Is there any possible way to make the method Process throw the exception NotAbstractedException without changing the class i am loading dynamically or no changing ObjectCaller ?
Just test it by passing it a namespace which contains a class called Main which isn't derived from Window.
Now you may find that tricky because if Type.GetType(string) is passed a value which is a non-assembly-qualified name, it will only look in mscorlib and the calling assembly - which in your case is the production code assembly. So your options are:
If you only ever want to use types from that assembly, then keep your current call to Type.GetType, but add a unit test to ensure that you don't have any classes called Main which aren't derived from Window. At that point, you can get rid of the IsSubclass test
Otherwise, allow the caller to pass in an assembly or assembly name - allowing you to put appropriate classes in your unit test assembly instead.
I used this code in c++ to use a class (that I defined before)in my other Apps.
#include class_name ;
How can I define a public class that could be used in all apps?
Thanks
To access classes from external assemblies you must add a reference to an external assembly. This will allow you to access public classes from the external assembly.
To specify a class from a namespace outside your current scope you must prefix the class's type specifier with its namespace name. To avoid this overhead, you can "include" the external namespace with the using directive.
Multiple namespaces can exist within a single assembly.
Assembly Fruit:
namespace Common
{
public class Strange
{
var mystery = new Mystery() // Won't compile, no reference to Mystery.
}
}
namespace Fruit
{
public class Orange
{
}
}
Assembly Vegetables:
References Fruit
namespace Common
{
public class Mystery
{
}
}
namespace Fungi
{
public class Mushroom
{
}
}
namespace Vegetables
{
using Common;
public Class Carrot
{
var strange = new Strange() // Compiles correctly.
var mystery = new Mystery() // Compiles correctly.
var orange = new Orange() // Won't compile, what's an Orange?
var orange = new Fruit.Orange() // Compiles correctly.
var mushroom = new Mushroom() // Won't compile, what's a Mushroom?
var mushroom = new Fungi.Mushroom() // Compiles correctly.
}
}
You need to create a Class Library project, which compiles to a DLL file.
You can then add a reference to it in other projects.
You have to include the namespace as below and also add any references if in another project.
using class_namespace;
If the other class is public or internal (and in the same assembly if they are internal), is in the same project, and has the same namespace, then you don't need to do anything at all. You will be able to refer to the other class by just using it's class name.
If they are in different namespaces then you can use a using statement (at the top of the file) to bring the other namespace into scope, or you can refer to the other class using the fully qualified name (i.e. OuterNamespace.InnerNamespace.ClassName) every time you use the class. (Which almost nobody ever does, everyone just uses using statements because they are so much more convenient.)
If the class is in another project entirely then you will need to add a reference to that class through visual studio. If you are creating a project that is designed to be referenced by other projects then it's project type should be a "class library".
Every class is created under a namespace
namespace abc{
public MyClass{
//functionality
}
}
To use your class on a different application,you need to import the namespace.
using abc;
public class usingClass{
MyClass obj = new MyClass();
}