Html TypeProvider MSBuild compilation issue - f#

I am using multiple type providers two of them HTML type providers. Everything compiles using Visual Studio, however when using MSBuild one of the html type providers does not generate the type system and I will get errors such as:
FS0072: Lookup on object of indeterminate type based on information prior to
this program point. A type annotation may be needed prior to this program point to constrain the type of the object.
FS0039: The field, constructor or member 'Descendants' is not defined (while accessing the Descendants collection of the Html property).
Both of these errors are probably just caused by the fact that the type provider does not generate the types correctly when building with MsBuild.
Are there any parameters specific to Visual Studio/MsBuild which would affect type providers? It seems that this is linked to the HTML file itself, because as said it works with other files, but I don't see any reason why it works in VS and does not work using MsBuild.

Related

how to change the dll reference file type assembly to active x

I have one dll, its been referenced in two projects, in one project it shows as
In another project it shows as
Can anybody let me know why same dll shows different properties in visual studio ?
Because I m getting "cannot be used across assembly boundaries because it has a generic type argument that is an embedded interop type" error when i build the project which shows the reference as assembly.

F# IDE scripting support for accessing internal types in referenced assemblies

Usually for non-scripting C#/F# project, one can specify a InternalsVisibleTo attribute in the dependency assembly and be able to get intellisense for its internal types in the IDE. But in F# scripting, how would I configure the dependency assembly with respect to the IDE I'm using in order to get intellisense for internal types? Of course in order for the script to run by fsi I assume I'd need something like
[assembly:InternalsVisibleTo("fsi")]
But in order to get the IDE support should I also specify every known IDE in the dependency assembly? That doesn't seem to scale very well.
I did a code search and found this where fsc, fsi, compiler service assembly, and their strong name versions, etc. are all specified, seemingly to accommodate IDEs. This is exactly what concerns me and I don't want to litter my assemblies with these. Is there a better way?

TEmbeddedWB & Console

When I tried to compile EmbeddedWB in Console it complains about some OleCtrls unit. Yet normal Webbrowser compiles without no problem.
How to compile it under Console?
[dcc64 Fatal Error] SHDocVw_EWB.pas(66): F1026 File not found: OleCtrls.dcu'
The issue is unit scope names. A console application by default has different unit namespace aliases from a forms application. Solve the problem by either:
Using fully qualified unit names. The full name for that unit is Vcl.OleCtrls.
Add missing unit scope names (in your case Vcl) to your console application's project configuration.
Since you are compiling third party code, it will be preferable for you not to modify that third party code. Hence option 2 is the way forward.
There may be other unit scope names that are needed. Make sure you add them all. And make sure that you are using the latest source for the component, obtained from the VCS repo and double check that it does indeed support XE4.
Note that my assumption is that by console you mean a console application. If you actually mean command line compilation then the answer is still essentially the same. You'll need to make sure that the unit scope names are specified when compiling. Normally that would be done in the project configuration and msbuild would pick them up and pass them on to dcc32 or dcc64.

Can I access types created in F# Interactive with System.CodeDom?

I am creating my type in FSX and passing those types into the Razor templating engine with the open source RazorEngine project.
Hosting Razor outside of ASP.NET requires compiling the Razor templates. If I pass a model created in FSX into the template, will System.CodeDom be able to have access to that type created by FSI? The basic error that I get is "The type or namespace name 'FSI_0004' could not be found".
Code that's compiled using System.CodeDom cannot generally have access to the code loaded in F# Interactive - the CodeDom essentially writes the C#/F# source code to disk and then invokes the command line compiler on the code (and the command line compiler cannot reference code loaded in F# Interactive).
There may be a way to get it working though - You could use the F# CodeDom provider from PowerPack. You could modify it to generate the source code (as it currently does) and then send the generated code to F# Interactive (instead of invoking command line compiler). This way, the code compiled on-the-fly could see F# Interactive code.
There are some issues that need to be resolved
Is it possible to provide your own CodeDom provider to RazorEngine?
The F# CodeDom provider may not correctly handle code generated by Razor (so you may need to fix/workaround a few things in the F# CodeDom provider). You may also need to modify it to generate code that works nicely with F# interactive (e.g. remove top-level namespaces)
What instance of F# Interactive do you want to use? (And how to get standard input, so that you can send your code there)
Do you need to load the compiled assembly and pass it back to Razor? I'm not sure if this can be done with F# Interactive.
These all depend on your scenario - but I guess that it may be possible to get what you want (possibly with some workarounds).

Dynamically loaded BPL's sharing code / passing objects

I was toying around with the idea of using dynamically loading BPL's and passing object instances from the main app to a method in a BPL. This poses a problem units between used by the application and by the BPL.
I wrote a small little prototype which did this and was curious how Delphi internally manages differences between classes defined in the app vs. the BPL.
For example, say a basic Widget class like:
TmyWidget = class
private
fId:Integer;
fDescription:String;
public
procedure DoSomething1();
end;
Now the app and the BPL are built using the unit containing TmyWidget class. Later, something changes in TMyWidget and the app is rebuilt, but the BPL is not (or vice-versa.) I added another method DoSomething2() and created an instance of TmyWidget in the app and passed it to the BPL for processing and in the basic example, it worked. But it's obviously fraught with potential problems.
If another dynamically loaded BPL also uses TmyWidget then things get even more interesting. It seems to work, but it definitely doesn't feel ideal.
The main question is - how does one typically pass objects to and from the main application and DLLs or BPLs? I've never attempted it before and likely for a good reason, but I've got this idea that lends itself to this approach...
I'd imagine that the best approach is to serialize the object and pass those bytes over and deserialize it in the DLL/BPL with this process being mindful of potential version differences between the host and the dynamically loaded module but I was hoping the new SimpleSharedMem option might bring this new functionality without the overhead of serialization, but it seems to be not very useful unless you are strict in keeping the app and dll rebuilt on any shared code changes...but in this prototype, the app would stay fairly constant and the dynamically loaded modules would be changing frequently with functionality being added to TmyWidget. (The server app serves as the factory for building TmyWidget's based on client requests and the app would pass instances to the various modules for processing.)
...was curious how Delphi internally manages differences between classes defined in the app vs. the BPL
Delphi manages this by not allowing it. You can't have a unit with the same name in multiple packages at the same time: if you do, you get an error message saying something similar to Package XYZ already contains ABC (haven't seen that in a while...). Since the type name includes the unit name, you can't have the same type in two different packages. Unless it's a Interface defined by it's GUID, but that's a different story.
... how does one typically pass objects to and from the main application and DLLs or BPLs?
You don't pass objects to DLL, that's not a good idea. When you need to pass objects to a BPL, make sure the base class for that BPL is defined into an 3rd BPL.
Example. Polymorphic behavior for your TmyWidget is probably defined using some virtual methods. Make sure you have a TmyWidgetBase class that defines all of those virtual methods, derive all your TmyWidget's from that base class and pass around objects with the type TmyWidgetBase. Make sure the TmyWidgetBase class is in it's own Package.
When I attempted doing this I ended up with an tiny "bootstrap" exe and lot's of BPL's. Essentially all the logic was in BPL's, to facilitate passing objects around.
One of the projects I've worked on has successfully used a large number of runtime packages for more than a decade now so I'll share a few of my experiences dealing with packages.
As Cosmin pointed out different packages cannot contain the same units. If you use implicit linking, by adding a package to the requires clause of another package or by adding a package to the the Runtime packages list in Project Options the compiler will do the work for you and report one of the following error messages:
E2199: Packages '%s' and '%s' both contain unit '%s' (if your compiling project that depends on two packages containing the same unit)
E2200: Package '%s' already contains unit '%s' (if your compiling a package that contains a unit this is already contained in one of the packages it depends on)
If you are using explicit linking, using LoadPackage, a check will normally be attempted a runtime (though it can be circumvented) and raise an:
EPackageError: Cannot load package
'%s.' It contains unit '%s', which is
also contained in package '%s'
Resolving these errors isn't really all that difficult.
If you have two packages that both need to use a unit just let one of them contain the unit and the other one require the first.
If you have two packages that need to use each other's contained unit you'll have to move those units to an new package that both can depend on.
Implicitly linked packages have the advantage that you can directly access class definitions as though they were statically linked. Just add a unit to the uses clause of the unit you need to use it in. The compiler and the runtime environment take care of resolving everything.
Explicitly linked packages will need to rely on class registration in the initialization section.

Resources