I need to find if specific interface is used in project, I just found something like
Type IType = Type.GetType("iInterfaceName"); // I want to look in whole project, not in one file
if (IType == null)
{
Text = "Interface Not Exist";
}
else
{
Text = "Interface Exist";
}
I am not sure if this is correct but this is the latest thing I found and in doesn't work,
any help greatly appreciated...
Use Assembly.Load before you go for GetType as follows:
Assembly.Load("YourProjectName")
.GetType("iInterfaceName");
Assume that you have the following interface:
public interface IFoo
{
}
You can find out if there's any type implementing it this way:
var isImplemented = Assembly.GetExecutingAssembly().
GetTypes().
Any(t => t.IsAssignableFrom(typeof (IFoo)));
To use the above, add to your using directives:
using System.Linq;
For .NET 2.0:
var isImplemented = false;
foreach (var t in Assembly.GetExecutingAssembly().GetTypes())
{
if (!t.IsAssignableFrom(typeof (IFoo))) continue;
isImplemented = true;
break;
}
//Operate
Related
I'm creating an expo sender application which is web based, but I have a problem compiling the project. It keeps me saying
"Type or namespace definition, or end-of-file expected"
My code looks like this and I've got it from here
using MobileServices.Client;
using MobileServices.Models;
using System;
using System.Collections.Generic;
using System.Linq;
var expoSDKClient = new PushApiClient();
var pushTicketReq = new PushTicketRequest()
{
PushTo = new List<string>() { "..." },
PushBadgeCount = 7,
PushBody = ""
};
var result = expoSDKClient.PushSendAsync(pushTicketReq).GetAwaiter().GetResult();
if (result?.PushTicketErrors?.Count() > 0)
{
foreach (var error in result.PushTicketErrors)
{
Console.WriteLine($"Error: {error.ErrorCode} - {error.ErrorMessage}");
}
}
var pushReceiptResult = expoSDKClient.PushGetReceiptsAsync(pushReceiptReq).GetAwaiter().GetResult();
if (pushReceiptResult?.ErrorInformations?.Count() > 0)
{
foreach (var error in result.ErrorInformations)
{
Console.WriteLine($"Error: {error.ErrorCode} - {error.ErrorMessage}");
}
}
foreach (var pushReceipt in pushReceiptResult.PushTicketReceipts)
{
Console.WriteLine($"TicketId & Delivery Status: {pushReceipt.Key} {pushReceipt.Value.DeliveryStatus} {pushReceipt.Value.DeliveryMessage}");
}
This is my first C# application that I'm building and I have searched the error but with no result. Can you please help me how to solve this. I know that is something simple but I really need help because I'm stuck.
You need to declare both a namespace and a class like this, and then put it in a function.
Every piece of code in c# needs to be declared inside a type (that could be a class, or a struct or an interface etc.
All types in turn are declared inside interfaces, which are logical groupings of types and other interfaces.
All (or most of it) of your code modeling behavior, should then be declared inside functions.
using MobileServices.Client;
using MobileServices.Models;
using System;
using System.Collections.Generic;
using System.Linq;
namespace mynamespace {
public class ExpoClient {
public void DoPushSend() {
var expoSDKClient = new PushApiClient();
var pushTicketReq = new PushTicketRequest()
{
PushTo = new List<string>() { "..." },
PushBadgeCount = 7,
PushBody = ""
};
var result = expoSDKClient.PushSendAsync(pushTicketReq).GetAwaiter().GetResult();
if (result?.PushTicketErrors?.Count() > 0)
{
foreach (var error in result.PushTicketErrors)
{
Console.WriteLine($"Error: {error.ErrorCode} - {error.ErrorMessage}");
}
}
var pushReceiptResult = expoSDKClient.PushGetReceiptsAsync(pushReceiptReq).GetAwaiter().GetResult();
if (pushReceiptResult?.ErrorInformations?.Count() > 0) {
foreach (var error in result.ErrorInformations)
{
Console.WriteLine($"Error: {error.ErrorCode} - {error.ErrorMessage}");
}
}
foreach (var pushReceipt in pushReceiptResult.PushTicketReceipts)
{
Console.WriteLine($"TicketId & Delivery Status: {pushReceipt.Key} {pushReceipt.Value.DeliveryStatus} {pushReceipt.Value.DeliveryMessage}");
}
}
}
}
Be careful, the code in the repository is a snippet of the whole, possibly needing to be broken down to more functions. My fix only intends to make your code compile.
It looks like the code sample you're using is written in C# 9, which is currently in preview. This version introduces a new feature called top-level statements, which allows you to write code without enclosing it in a method of a class. You're probably using an earlier version, which expects the entry point to be in a static method named Main.
I'm trying to get a small plugin mechanism running by reflecting an dll file providing my class Plugin (implementing my Plugin-Interface shared among dll and main project / sorry for naming both the same) offering an attribute of type string and a main-method activate:
Interface:
public interface Plugin
{
string pluginName{get;set;}
void activate(System.Windows.Forms.Form main);
}
dll class:
public class Plugin : WhiteA.Plugin
{
public string pluginName{get;set;}
public void activate(System.Windows.Forms.Form main){
//find the right form to modify it
IEnumerable<System.Windows.Forms.ComboBox> ie= GetControlsOfType<System.Windows.Forms.ComboBox>(main);
System.Windows.Forms.ComboBox cb=GetControlsOfType<System.Windows.Forms.ComboBox>(main).FirstOrDefault();
cb.Items.Add("Modification");
System.Windows.Forms.MessageBox.Show(cb.SelectedItem.ToString());
}
public static IEnumerable<T> GetControlsOfType<T>(System.Windows.Forms.Control root)
where T : System.Windows.Forms.Control
{
var t = root as T;
if (t != null)
yield return t;
var container = root as System.Windows.Forms.ContainerControl;
if (container != null)
foreach (System.Windows.Forms.Control c in container.Controls)
foreach (var i in GetControlsOfType<T>(c))
yield return i;
}
}
So here comes the problem, there is no type named "Plugin" to be found in the assembly. Tried to get all types from all assemblies in the directory, get all methods/members/custom attributes from them, have them logged etc, but there is nothing of my class Plugin to be found, while the dll definitely is being found, as it doesn't return the MessageBox.
string[] files=new string[]{};
string path="Error retrieving path";
try{
path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
files = System.IO.Directory.GetFiles(path, "*.dll");
}catch(Exception exF){
}
if(files.Length>0){
foreach (string dll in files){
try{
System.Reflection.Assembly sampleAssembly = System.Reflection.Assembly.LoadFrom(dll);
Type myType = sampleAssembly.GetType("Plugin");
System.Reflection.MethodInfo method = myType.GetMethod("activate");
object myInstance = Activator.CreateInstance(myType);
method.Invoke(myInstance, new object[]{this});
}catch(Exception exL){
}
}
}else{
MessageBox.Show("No working plugins detected in " + path.ToString(), "Nothing to activate", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
}
I know my code probably looks really messy to you all - I think the last try-block is the only thing relevant here, wanted to put in the class itself and the interface for a little bit transparency though - and my english isn't perfect, but I hope someone can help me out finding my attribute+method in the assembly.
EDIT:
try{
System.Reflection.Assembly sampleAssembly = System.Reflection.Assembly.LoadFrom(dll);
List<Type> list= sampleAssembly.GetTypes().Where(p =>
p.Namespace == dll &&
p.Name.Contains("Plugin")
).ToList();
Type myType=list.FirstOrDefault();
//Type myType = sampleAssembly.GetType("Plugin");
System.Reflection.MethodInfo method = myType.GetMethod("activate");
object myInstance = Activator.CreateInstance(myType);
method.Invoke(myInstance, new object[]{this});
}
I did change it according to Getting all types in a namespace via reflection
Still the same result, what did I do wrong?
As pointed out by #stuartd:
Type myType = sampleAssembly.GetType("WhiteA_Plugin_PausedVideo.Plugin");
is the solution, missed the namespace
cb.Items.Add("Modification");
doesn't work though...any suggestions?
Got it to work getting the form's children by Controls["nameOfChild"] directly, that help method to fetch all objects by class seems to be wrong here.
Plugin works now, thanks!
I want to check if a c# project is NUnit or MSTest based. Currently, I read csproj's file and look for a specific string like below.
const string MSTEST_ELEMENT = "<TestProjectType>UnitTest</TestProjectType>";
const string NUNIT_ELEMENT = #"<Reference Include=""nunit.framework"">";
var file = File.ReadAllText("C:\myfile.csproj");
if (file.Contains(NUNIT_ELEMENT))
{
result = TestProjectType.NUnit;
}
else if (file.Contains(MSTEST_ELEMENT))
{
result = TestProjectType.MSTest;
}
It works as I expected but looking for a specific text in a file is ugly for me. Is there a better way to do this?
Check the solution for dll reference "NUnit.framework.dll" . For NUnit, it is neccesary to provide reference of that dll.
You could use a reflection-based approach - load the DLL from the test project, get all of the public types in it, and check for [TestClass] attributes to indicate if it's MSTest, etc.
This sample (works but not really tested) gives an example. You could make it better by referencing the test attribute types in whatever runs this code so you could do proper type comparisons instead of strings.
class Program
{
static void Main(string[] args)
{
var path = #"Path\To\Your\Test\Dll";
//load assembly:
var assembly = Assembly.LoadFile(path);
//get all public types:
var types = assembly.GetExportedTypes();
foreach (var t in types)
{
Console.WriteLine(t.Name);
//check for [TestClass] attribute:
var attributes = t.GetCustomAttributes();
foreach (var attr in attributes)
{
var typeName = attr.TypeId.ToString();
Console.WriteLine(attr.TypeId);
if (typeName== "Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute")
{
Console.WriteLine("It's MSTest");
}
else if (typeName == "Nunit.Tests.TestFixture") //not sure if that's the right type id :)
{
Console.WriteLine("It's NUnit");
}
else
{
Console.WriteLine("I Have no idea what it is");
}
}
}
Console.ReadLine();
}
}
Actual situation is, that I added to the MvxViewTypeResolver class the "Fragment"-Case, so it does look like this:
#region Copyright
// <copyright file="MvxViewTypeResolver.cs" company="Cirrious">
// (c) Copyright Cirrious. http://www.cirrious.com
// This source is subject to the Microsoft Public License (Ms-PL)
// Please see license.txt on http://opensource.org/licenses/ms-pl.html
// All other rights reserved.
// </copyright>
//
// Project Lead - Stuart Lodge, Cirrious. http://www.cirrious.com
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.Views;
using Cirrious.MvvmCross.Binding.Android.Interfaces.Binders;
namespace Cirrious.MvvmCross.Binding.Android.Binders
{
public class MvxViewTypeResolver : IMvxViewTypeResolver
{
private Dictionary<string, Type> _cache = new Dictionary<string, Type>();
public IDictionary<string, string> ViewNamespaceAbbreviations { get; set; }
#region IMvxViewTypeResolver Members
public virtual Type Resolve(string tagName)
{
Type toReturn;
if (_cache.TryGetValue(tagName, out toReturn))
return toReturn;
var unabbreviatedTagName = UnabbreviateTagName(tagName);
var longLowerCaseName = GetLookupName(unabbreviatedTagName);
var viewType = typeof(View);
#warning AppDomain.CurrentDomain.GetAssemblies is only the loaded assemblies - so we might miss controls if not already loaded
var query = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where viewType.IsAssignableFrom(type)
where (type.FullName ?? "-").ToLowerInvariant() == longLowerCaseName
select type;
toReturn = query.FirstOrDefault();
_cache[tagName] = toReturn;
return toReturn;
}
private string UnabbreviateTagName(string tagName)
{
var filteredTagName = tagName;
if (ViewNamespaceAbbreviations != null)
{
var split = tagName.Split(new char[] {'.'}, 2, StringSplitOptions.RemoveEmptyEntries);
if (split.Length == 2)
{
var abbreviate = split[0];
string fullName;
if (ViewNamespaceAbbreviations.TryGetValue(abbreviate, out fullName))
{
filteredTagName = fullName + "." + split[1];
}
}
}
return filteredTagName;
}
#endregion
protected string GetLookupName(string tagName)
{
var nameBuilder = new StringBuilder();
switch (tagName)
{
case "View":
case "ViewGroup":
nameBuilder.Append("android.view.");
break;
case "fragment":
nameBuilder.Append("android.app.");
break;
default:
if (!IsFullyQualified(tagName))
nameBuilder.Append("android.widget.");
break;
}
nameBuilder.Append(tagName);
return nameBuilder.ToString().ToLowerInvariant();
}
private static bool IsFullyQualified(string tagName)
{
return tagName.Contains(".");
}
}
}
Now it is submitting the correct longLowerCaseTagName (android.app.fragment) but in the query it isn't able to resolve the type.
My suggestion is, that the fragment-control isn't loaded when the type should be resolved. Maybe there is an other way to get the type resolved?
Also if I add a custom type (giving the tag Mvx.MyCustomType in the axml) it doesn't get resolved. Do I have to add something in the MvxBindingAttributes.xml in this case?
Thanks for the help!
First an explanation of the code:
The custom XML inflater factory used by the MvvmCross Binder tries to load Views in a very similar way to the standard 2.x Android XML inflater.
The default code for the view type resolution is indeed in: https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Binding/Android/Binders/MvxViewTypeResolver.cs
If your xml contains a name such as <MyCompany.MyProject.MyViews.MyFirstView /> then the view type resolver:
first checks for abbreviations and expands these into full namespaces - by default the only known abbreviation is Mvx. which is expanded to: Cirrious.MvvmCross.Binding.Android.Views.. If you want to add more abbrevations then override ViewNamespaceAbbreviations in https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Binding/Android/MvxBaseAndroidBindingSetup.cs
then checks to see if the unabbreviated name is a non-namespaced name. If it is, then it assumes that the class is the Android namespace and prepends it with android.view. or android.widget.
then converts the fully namespaced name to all lowercase as a case-insensitive lookup key
uses that lowercase key to search all Types which derive from View in all loaded assemblies.
caches the result (whether its null or not) in order to speed up subsequent inflations.
All of this behaviour was designed to match the default Android xml view inflation code in http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.6_r1/android/view/LayoutInflater.java#LayoutInflater.createViewFromTag%28java.lang.String%2Candroid.util.AttributeSet%29
With that explanation out of the way - here's an answer to your questions:
MvvmCross does not yet currently contain any Fragment support. The official MonoDroid fragment support itself was only released last week, and I've not yet had anybody request fragments - Android "fragmentation" seems to have kept most people back on Activity and Dialog based code.
Briefly ;ooking at the documentation, fragment isn't an Android View - it looks like Fragment inherits directly from Java.Lang.Object - see http://developer.android.com/reference/android/app/Fragment.html
Because of this, there's no way that the MvvmCross ViewTypeResolver will currently work with fragments.
I would suggest that if you need both mvvmcross and fragments today, then your best bet is to replace the default resolver (using IoC) with your own resolver - but I can't offer much advice on this as I haven't yet fully read and understood the droid docs on http://developer.android.com/guide/topics/fundamentals/fragments.html
From my experience in creating the current inflation code, then I think you will find the source essential reading when you do this - e.g. see : http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/view/LayoutInflater.java#LayoutInflater.createViewFromTag%28android.view.View%2Cjava.lang.String%2Candroid.util.AttributeSet%29
I can't give you any information on when official mvvmcross fragment support will be available - it's not something that is currently scheduled.
Custom views are supported, but will not normally live in the Mvx. abbreviated namespace.
They are much more likely to live in your UI application namespace, or in some shared library.
To see a custom view in action, see the PullToRefresh example in the tutorial - https://github.com/slodge/MvvmCross/blob/master/Sample%20-%20Tutorial/Tutorial/Tutorial.UI.Droid/Resources/Layout/Page_PullToRefreshView.axml
I have a few dll files and I want to export all public classes with methods separated by namespaces (export to html / text file or anything else I can ctrl+c/v in Windows :) ).
I don't want to create documentation or merge my dlls with xml file. I just need a list of all public methods and properties.
What's the best way to accomplish that?
TIA for any answers
Very rough around the edges, but try this for size:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace GetMethodsFromPublicTypes
{
class Program
{
static void Main(string[] args)
{
var assemblyName = #"FullPathAndFilenameOfAssembly";
var assembly = Assembly.ReflectionOnlyLoadFrom(assemblyName);
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);
var methodsForType = from type in assembly.GetTypes()
where type.IsPublic
select new
{
Type = type,
Methods = type.GetMethods().Where(m => m.IsPublic)
};
foreach (var type in methodsForType)
{
Console.WriteLine(type.Type.FullName);
foreach (var method in type.Methods)
{
Console.WriteLine(" ==> {0}", method.Name);
}
}
}
static Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
var a = Assembly.ReflectionOnlyLoad(args.Name);
return a;
}
}
}
Note: This needs refinement to exclude property getters/setters and inherited methods, but it's a decent starting place
Have you had a look at .NET Reflector from RedGate software. It has an export function.
You can start here with Assembly.GetExportedTypes()
http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getexportedtypes.aspx