My issue goes like this:
There is a project called myframework. It has some extension methods defined in it as follows:
namespace myframework
{
public static class Helpers
{
public static bool ContainsAll(this string obj, string[])
{
return true;
}
}
}
It also has some other stuff like interfaces, etc, etc.
There is a second class I generate via System.CodeDom classes. The generated output is somewhat like this:
using myframework;
public class A: IMyFrameworkInterface
{
public void foo()
{
string s ="HELLO";
if(s.ContainsAll(some_arr))
return;
}
//More methods defined...
}
The compiler options I pass which is created prior to the actual compile call references the correct assemblies
var cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("myframework.dll");
The code compilation modules are written in a different project. The particular class responsible for this also nicely gives us access to a list of CompilerError object via which we can learn the result of compilation.
Issue1: When I tried this in an asp.net project the compiler threw error saying it could not find metadata file myframework.dll (despite it being referenced in the project).
Issue2: When I tried it with a windows forms project. It gave a different error. This time saying that string does not contain definition for ContainsAll()
How to solve these two specific problems?
Found out the answer to this after a bit digging up. I was using .net framework 3.5. The codedom compiler apis targets v2.0 of the framework by default. Hence, you have to manually specify the correct framework:
var cp = new CompilerParameters(
new Dictionary<string,string>() { {"CompilerVersion", "v3.5"} });
For the compilation to work within an asp.net environment you'd have to actually point the references to the correct location. Hence you'd have to do something like follows:
cp.ReferencedAssemblies.Add(
HttpContext.Current.Server.MapPath(
"bin\\myframework.dll"));
My references:
http://blogs.msdn.com/b/lukeh/archive/2007/07/11/c-3-0-and-codedom.aspx
.Net 3.5 CodeDom Compiler generating odd errors
And comments in the question's post. :)
Related
I have created a Visual Studios Extension using the AsyncPackage Class that looks something line this:
public sealed class Tools : AsyncPackage, IDisposable
{
internal const string PrjCATIDCSharpFileBrowseObject = "{8D58E6AF-ED4E-48B0-8C7B-C74EF0735451}";
private readonly List<IDisposable> _extenderProviders = new List<IDisposable>();
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await base.InitializeAsync(cancellationToken, progress);
_extenderProviders.Add(new BrowseProvider(this, PrjCATIDCSharpFileBrowseObject));
}
}
I am getting 4 Errors with the code CS1748 on BrowseProvider. What I do not understand is that the Errors it gives are for Types that BrowseProvider does not use. One of the errors is for IAsyncServiceProvider, but BrowseProvider uses IServiceProvider. AsyncPackage does inherit IServiceProvider, but I changed BrowseProvider to use IAsyncServiceProvider however this did not solve the problem. Creating a new BrowseProvider object anywhere in Tools shows this CS1748 error.
I have looked around and found that this error is caused by a reference DLL. I set Microsoft.VisualStudio.Shell.Framework to have its Embed Interop Type Property set to False, but the errors still persists.
All of my code shows no errors except when I try and create a BrowseProvider object from with in the Tools Package. I do not understand why creating a new object anywhere in the Tools Class shows errors for type that are no being used.
Please make sure that you reference the correct dll or the nuget package in your project. Usually you get this error, when there is no reference.
VS2012 for desktop .net framework 4.5 normal windows forms applications, not WPF
Hello, I tried to search for an answer, but I'm not sure of the correct terminology. I've managed to break my code, and can't understand what I've done wrong. (i didn't think i had changed anything, but ...)
I have a solution which contains 2 projects. The first project is an executable program, and the second is a DLL, which is loaded at run time and used by the first project.
the first project contains a form, and a static class with public static strings in the same namespace. (and some other unconnected classes). specifically:
namespace project1_namespace
{
static class settings
{
public static string some_words = "some words in a string";
}
class dll_callback{
//.. some public methods here
}
dll_callback dllcallback; // instance is initialised in the code (not shown)
Form form;
public partial class frm_splash : Form
{
private void frm_splash_FormClosing(object sender, FormClosingEventArgs e)
{
// this function actually loads the DLL, ensuring its the last step
//... some error checking code removed for brevity
Assembly assembly = Assembly.LoadFrom("c:\dllpath\project2.dll");
Type type_init = assembly.GetType("project2_class");
object init = Activator.CreateInstance(type_init, form, dllcallback);
//... some error checking code removed for brevity
}// end method
}// end form class
}// end namespace
when the form is closing, the method shown above is called which calls the second projects class project2_class constructor.
in project 2, the DLL, there is:
namespace project2_namespace
{
// how did i get this working to reference "settings" class from project 1??
public class project2_class
{
public project2_class(project2_namespace.Form1 form_ref, object callback)
{
settings.some_words = "the words have changed";
//... some more stuff
}
}
}
Now, i was experimenting with some code in an entirely different part of project2, and VS2012 suddenly started refusing to compile stating:
error CS0103: The name 'settings' does not exist in the current context
the standard solution to this appears to be to add a reference to project2, but that would create circular dependencies because project 1 calls 2 as a DLL.
I really honestly don't think i had changed anything relevant to this, but also clearly I have.
looking at it, i cant see how project 2 would have access to a class in project 1 without a reference, but the list of arguments to the project2_class constructor doesn't include one, and I am absolutely positive that it hasn't changed (and I cant change it for backwards compatibility reasons).
would really appreciate help with this, as its been a lot of work to get this working.
as a side note, I've definitely learned my lesson about not using source control. and not making "how this works" comments instead of "what this does" comments.
may dynamic help you? You can not get the setting string at complie time.
So here is my issue. I have a complex archetecture of interfaces and abstract classes that I am trying to load up via Assembly.LoadFrom("x.dll"). When certain types that have an interface implementation where the implementation is explicit in a base class are trying to be loaded, I am getting a TypeLoadException saying:
Method 'MyMethod' in type 'MyPart2DerivedType' from assembly 'MyPart2Assembly, version...' does not have an implementation. I am trying to understand why this is as I have gone through several articles and have even attempted to delete the obj files and dlls manually. Here are the references to what I have done so far:
Solution to TypeLoadException
TypeLoadException says 'no implementation', but it is implemented
Visual Studio Forumns: TypeLoadException
Private accessors and explicit interface implementation
So here is my example code:
//This is in project 1
public interface IFooPart1
{
void DoStuff();
}
//This is in project 2
public interface IFooPart2
{
void DoOtherStuff();
}
//This is in project 3
public interface IFooPart3: IFooPart1, IFooPart2
{
void DoEvenMoreStuff();
}
//This is in project 4
public abstract class MyBaseType: IFooPart1, IFooPart2
{
void IFooPart1.DoStuff()
{
DoStuffInternal();
}
void IFooPart2.DoOtherStuff()
{
DoOtherStuffInternal();
}
}
//This is in project 5
public class MyDerivedType: MyBaseType, IFooPart3
{
public void DoEvenMoreStuff()
{
//Logic here...
}
}
//Only has references to projects 1, 2, & 3 (only interfaces)
public class Program
{
void Main(params string[] args)
{
//Get the path to the actual dll
string assemblyDll = args[0];
//Gets the class name to load (full name, eg: MyNameSpace.MyDerivedType)
string classNameToLoad = args[1];
//This part works...
var fooAssembly = Assembly.LoadFrom(assemblyDll);
//Here we throw a TypeLoadException stating
// Method 'DoStuff' in type 'MyDerivedType' from assembly 'Project 5...' does
// not have an implementation.
Type myDerivedTypeExpected = Assembly.GetType(classNameToLoad);
}
}
Note: If I move the explicit implementation to MyDerivedType instead of MyBaseType it works... but I don't get why I would have to do that. Seems like I should be able to. This code is only an example, the actual code has a factory that returns the loaded class but only via the interface type. (eg: var myDerivedType = GetInstance();)
Okay for everyone that is interested in my stupid fix. Here was my problem:
Project6 (which was the console app) has PROJECT references to the other projects, not references to the dlls in the location that they are supposed to build to. The other projects actually were being built to a specific repository area. So, the console application was using it's own version of the dll's when it was trying to automatically load the dependancies. This evidently made some other type way down there that was being dynamically loaded to not be loaded because it was not in the same folder as the dlls that were there...
So in short, Assembly.LoadFrom might cause you to load an assembly twice, but .NET treats it like a different assembly!!! This may introduce some real odd errors when trying to dynamically load types!!!
Please learn from my frustration/mistake. Fiends don't let freinds DI alone (code review is key to catching this stupid stuff).
I've had a similar problem caused by one of my projects having a reference to an older version of a nuget package dependency. The older version didn't have an implementation for one of the methods.
I'm battling with the QuickFix engine in .Net (using the C++ DLL wrapper) to craft a TradeCaptureReportRequest message:
var req = new QuickFix44.TradeCaptureReportRequest();
req.set(new QuickFix.SubscriptionRequestType(QuickFix.SubscriptionRequestType.SNAPSHOT_PLUS_UPDATES)); // 263
req.set(new QuickFix.TradeRequestID("testing" + DateTime.Now.Second.ToString())); // 568
var nodates = new QuickFix44.TradeCaptureReportRequest.NoDates();
nodates.set(new QuickFix.TradeDate("20130201"));
req.set(nodates); // 580
Everything seems to look good until I call req.set(nodates), which causes a compiler error saying that "NoDates cannot be converted to a NoDates".
This boggles my mind since when I navigate to the metadata of the TradeCaptureRequest within the QuickFix dll, i am shown this.
public void set(NoDates value);
// as a member of QuickFix44.TradeCaptureReportRequest
if I go to the definition of NoDates it sends me to the QuickFix44.TradeCaptureReportRequest.NoDates Class defined within the QuickFix44.TradeCaptureReportRequest class.
however there is a NoDates Class defined within the QuickFix namesapace which compiles just fine when I do the following.
req.set(new QuickFix.NoDates(1));
I'm using Quickfix v4.0.30128 and the .Net wrapper for the C++ DLL.
If you look at the C# code for TradeCaptureReportRequest.set you'll find that it would like a QuickFix.NoDates type for the NoDates value:
// line: 1993
public void set(QuickFix.NoDates value)
{ setField(value); }
So change your C# to the following:
var nodates = new QuickFix.NoDates();
nodates.set(new QuickFix.TradeDate("20130201"));
req.set(nodates);
It appears you're using the QuickFix .Net wrapper over the C++, which is an abomination of .Net programming guidelines. I highly recommend you switch to QuickFIX/N, which is less horrible (but still awful looking).
F# declared namespace is not available in the c# project or visible through the object browser.
I have built a normal F# library project, but even after i build the project and reference it to my C# project, I am unable to access the desired namespace.
I am also unable to see it in the object browser, i get an error telling me that it has not been built. I am running on the september release can someone point out my error ?
F# Version 1.9.6.0
(6) Edit : Referencing the dll directly has fixed my problem, referencing the project allows me to compile but the intellisence does not work. When the dll is directly referenced the intellisence works perfectly.
This is the code found in the .fs file
#light
namespace Soilsiu.Core
module public Process =
open System.Xml.Linq
let private xname (tag:string) = XName.Get(tag)
let private tagUrl (tag:XElement) = let attribute = tag.Attribute(xname "href")
attribute.Value
let Bookmarks(xmlFile:string) =
let xml = XDocument.Load(xmlFile)
xml.Elements <| xname "A" |> Seq.map(tagUrl)
let PrintBookmarks (xmlFile:string) =
let list = Bookmarks(xmlFile)
list |> Seq.iter(fun u -> printfn "%s" u)
(5) Edit : Could ReSharper 4.0 be the problem?
(4) Edit : When i say the Object browser is unable to read the resulting assembly, i mean that when I try to open the assembly in the object browser i get an error telling me the project has not yet been built. yet again i can read the assembly using reflector.
(3) Edit : Reflector can Disassemble the dll but the Object Browser is unable to read it.
(2) Edit : I have Upgraded my F# version to 1.9.6.2 and still the same consequence
(1) Edit : I was able to Disassemble the dll to C# I get : (Everything seems to be fine here)
namespace Soilsiu.Core
{
[CompilationMapping(7)]
public static class Crawler
[CompilationMapping(7)]
public static class Process
}
[CompilationMapping(7)]
public static class Process
{
// Methods
static Process();
public static IEnumerable<string> Bookmarks(string xmlFile);
public static void PrintBookmarks(string xmlFile);
internal static string tagUrl(XElement tag);
internal static XName xname(string tag);
// Nested Types
[Serializable]
internal class clo#13 : FastFunc<XElement, string>
{
// Methods
public clo#13();
public override string Invoke(XElement tag#9);
}
[Serializable]
internal class clo#17 : FastFunc<string, Unit>
{
// Methods
public clo#17();
public override Unit Invoke(string u);
}
}
What if you reference the produced DLL directly (i.e., not via a project reference, but via a file reference)?
Maybe IntelliSense is just messed up? What compiler error do you get when you try to use it in C#? When you say "the object browser is unable to read it" what does that mean?
For what it's worth, I added this to a F# library project, referenced it (project) from a C# console app, and was able to use it. IntelliSense did not work at first though. (Had to rebuild.)
If you can make a solid repro, I'd suggest emailing it to F# bugs alias (fsbugs).
I tried the same thing. It looks as if Visual Studio and Resharper 4.0 doesn't understand F# for some reason. If you ignore the sea of red text and the lack of intellisense, it will compile fine.
Try
Make sure that C# project is targeted FULL .NET (NOT Client Profile).
Add references to assemblies into C# project which are used by F# project.