Show all Types of all references in project from an IWizard - .net-assembly

I was trying to create a Template that takes in a Type to substitute it's name in a template.
The template looks like this
using System;
using System.Collections.Generic;
using System.Text;
namespace $rootnamespace$
{
public class $safeitemrootname$<$TView$>
{
}
}
I substitute the $TView$ parameter with the selected Type in my custom IWizard.
public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
{
DTE dte = (DTE)automationObject;
Project project = dte.SelectedItems.Item(1) as Project;
VSProject vsProj = (VSProject)project.Object;
foreach (Reference reference in vsProj.References)
{
if (reference.SourceProject == null)
{
// Assembly reference
}
else
{
// Project reference
}
}
}
The real problem comes in here: how can I show a grid with all the Types in all of the referenced assemblies of a project?
I tried to do load the Assembly with Assembly.Load, Assembly.LoadFrom, Assembly.ReflectionOnlyLoad, Assembly.ReflectionOnlyLoadFrom and many others (also with AppDomain), but I alwais get an error asking to load the dependencies first.
Is there any way to get the defined types in all assemblies of a project with envDTE or Reflection?

Related

The name 'PropertySupport' does not exist in the current context

I would like to create a base class for observableObject generic enough for an observable object to derive from, but I hit some technical issue. This is an extract of the class. It is an abstract that implements interface INotifyPropertyChanged. But when I tried to use PropertySupport.ExtractPropertyName, I got compiler error saying 'PropertySupport' not exist in the current context. I am using VS2002. My intention was to create a library to host a small "framework" of my own and use it for different projects. Could anyone more well versed in the reflection point out what was wrong in my code to cause the compiler error?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace MyFramework
{
[Serializable]
public abstract class ObservableObject: INotifyPropertyChanged
{
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
var handler = this.PropertyChanged;
if (handler!=null)
{
handler(this, e);
}
}
protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression)
{
var propertyName = PropertySupport.ExtractPropertyName(propertyExpression);
this.RaisePropertyChanged(propertyName);
}
protected void RaisePropertyChanged(String propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
}
}
The error you are getting usually refers to a missing using directive or missing reference.
Looking at MSDN for the function you are trying to use it looks like you are missing the using directive Prism.ViewModel
using Microsoft.Practices.Prism.ViewModel;
If this doesn't fix your problem then you need to add a reference to the correct dll
Microsoft.Practices.Prism.Composition.dll
I've never used Prism but after copying your class, adding the correct reference & using directive it built ok.

The type or namespace name 'LinkedList' could not be found (are you missing a using directive or an assembly reference?

I have a fresh install of Visual Studio, the following code gives me the error in the title.
using System;
using System.Collections;
using System.Collections.Generic;
public class GenericCollection
{
public static void Main()
{
// Create and initialize a new LinkedList.
LinkedList<String> ll = new LinkedList<String>();
ll.AddLast("red");
ll.AddLast("orange");
ll.AddLast("yellow");
ll.AddLast("orange");
// Display the contents of the LinkedList.
if (ll.Count > 0)
{
Console.WriteLine("The item in the list is {0}.", ll.First.Value);
Console.WriteLine("The item in the list is {0}.", ll.Last.Value);
Console.WriteLine("The LinkedList contains:");
foreach (String s in ll)
Console.WriteLine(" {0}", s);
}
else
{
Console.WriteLine("The LinkedList is empty.");
}
}
}
I am not even using a custom class.
just from the System.Collections.Generic dll
I assume there is a problem with the references, since the code is correct.
Please help me , how can i fix this.
(PS: I am fairly new to coding)
System.Collections.Generic.LinkedList<T> exists in the System (System.dll) assembly.
Make sure you have a project reference to this assembly.
You can view your existing references by expanding the References section under the project in Solution Explorer.

How to uppercase entire variable in Resharper Template?

I have a situation where I want the variable to be capitalized for documentation eg
(trivalized for example)
///AT+$COMMAND$
void At$COMMAND$()
{
}
So I want the user of the template to type in something like "Blah" and that gets used in the method name, but the documentation part gets changed to "BLAH".
eg
///AT+BLAH
void AtBlah()
{
}
Can I do this? I see in the macros I can capitalize the first letter, but I'd like the whole word capitalized. Is it possible to create custom macros?
They just updated documentation to meet changes in macros in Resharper 8. You can check it at http://confluence.jetbrains.com/display/NETCOM/4.04+Live+Template+Macros+%28R8%29
With the new docs it is quite easy, my implementation goes here:
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using JetBrains.DocumentModel;
using JetBrains.ReSharper.Feature.Services.LiveTemplates.Macros;
using JetBrains.ReSharper.Feature.Services.LiveTemplates.Hotspots;
namespace ReSharperPlugin
{
[MacroDefinition("LiveTemplatesMacro.CapitalizeVariable", // macro name should be unique among all other macros, it's recommended to prefix it with your plugin name to achieve that
ShortDescription = "Capitalizes variable {0:list}", // description of the macro to be shown in the list of macros
LongDescription = "Capitalize full name of variable" // long description of the macro to be shown in the area below the list
)]
public class CapitalizeVariableMacro : IMacroDefinition
{
public string GetPlaceholder(IDocument document, IEnumerable<IMacroParameterValue> parameters)
{
return "A";
}
public ParameterInfo[] Parameters
{
get { return new[] {new ParameterInfo(ParameterType.VariableReference)}; }
}
}
[MacroImplementation(Definition = typeof(CapitalizeVariableMacro))]
public class CapitalizeVariableMacroImpl : SimpleMacroImplementation
{
private readonly IMacroParameterValueNew _parameter;
public CapitalizeVariableMacroImpl([Optional] MacroParameterValueCollection parameters)
{
_parameter = parameters.OptionalFirstOrDefault();
}
public override string EvaluateQuickResult(IHotspotContext context)
{
return _parameter == null ? null : _parameter.GetValue().ToUpperInvariant();
}
}
}

How do you instantiate an object that is not included in your C# project?

Note: All sample code is greatly simplified.
I have a DLL defined as:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
namespace RIV.Module
{
public interface IModule
{
StringWriter ProcessRequest(HttpContext context);
string Decrypt(string interactive);
string ExecutePlayerAction(object ParamObjectFromFlash);
void LogEvent(object LoggingObjectFromFlash);
}
}
Now, outside of my solution, other developers can define concrete classes and drop them into the BIN folder of my app. Maybe something like:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RIV.Module;
namespace RIV.Module.Greeting
{
public class Module : IModule
{
public System.IO.StringWriter ProcessRequest(System.Web.HttpContext context)
{
//...
}
public string Decrypt(string interactive)
{
//...
}
public string ExecutePlayerAction(object ParamObjectFromFlash)
{
//...
}
public void LogEvent(object LoggingObjectFromFlash)
{
//...
}
}
}
Now, in my app I would need to know that a new Module was available (I am guessing via web.config or something along those lines) and then be able to call it based off of some trigger in the database Campaign table (which maps to the module to use for that specific campaign).
I am trying to instantiate it this way:
var type = typeof(RIV.Module.Greeting.Module);
var obj = (RIV.Module.Greeting.Module)Activator.CreateInstance(type);
However, the compiler belches because a reference was never set to RIV.Module.Greeting.dll!
What am I doing wrong?
You need to use more reflection:
Load the assembly by calling Assembly.Load
Find the type by calling someAssembly.GetType(name) or searching someAssembly.GetTypes()
Pass the Type instance to Activator.CreateInstance
Cast it to your interface.
Instead of typeof(RIV.Module.Greeting.Module), try using
var type = Type.GetType("RIV.Module.Greeting.Module, RIV.Module.Greeting");
(i.e. load the type by specifying its assembly-qualified name as string) and casting to IModule.
This approach requires you to know the exact class and assembly names of the modules (as you wrote, they could be stored in web.config).
Alternatively, you could go for a completely dynamic plugin approach:
establish a convention that all module assemblies should be named "RIV.Module.XYZ"
scan the bin directory for matching DLLs
for each DLL, load it (e.g. Assembly.Load) and scan for types implementing IModule
instantiate all found types and cast to IModule

Help With Error C#: An object reference is required for the non-static field, method, or property RpgTutorial.Character.Swordsmanship

I am very new to C# and programming in general and I'm having the error (described in the title box) when I run this code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace RpgTutorial
{
public class HeroSkills : Character
{
public int Skill()
{
if (Hero.Swordsmanship = 10)
{
}
}
}
}
Now I know I need to create a reference to Swordsmanship, but how exactly would I do that? Thank you for any help!
If you're trying to access the Swordsmanship property of the same object that the method would be called for, then you can access it via the this reference:
if (this.Swordsmanship == 10)
{
...
}
Is a Hero a subclass of Character (or the other way around)? If so, you can reference the property Swordsmanship like this:
if (this.Swordsmanship == 10)
{
...
}
Otherwise if you are finding yourself needing to reference a 'hero', you can add a constructor (and property) to your HeroSkills class like this:
public HeroSkills : Character
{
public Hero CurrentHero
{
get;
set;
}
public HeroSkills(Hero hero)
{
this.CurrentHero = hero;
}
...
Note that the this keyword is not required, but signifies that the property you are accessing is a member of your class. This can help you in readability later on. You can then reference the CurrentHero around your class in your various methods like the Skill() as so:
if (this.CurrentHero.Swordsmanship == 10)
{
...
}
You would use your newly modified class elsewhere in code like this:
Hero player1 = //some hero variable
var skills = new HeroSkills(player1);
int currentSkill = skills.Skill();

Resources