Is there an alternate to TemplatePartAttribute in UWP? - c#

It took me a bit of time to discover this, but designer-specific attributes like TemplatePart are now causing issues with the release build of my UWP application.
Applying this attribute to your controls is using reflection.
[TemplatePart(Name = PART_Panel, Type = typeof(Panel))]
public class MyAwesomeControl : Control
{
...
}
And build output gives me this:
warning : Type 'Windows.UI.Xaml.Controls.Panel' was not included in
compilation, but was referenced in type 'MyAwesomeControl'. There may
have been a missing assembly.
If you want the build to work, I have to exclude that attribute. However, that defeats the purpose of a control library. Users of my library will not know that a Panel with the name PART_Panel is required in the template of MyAwesomeControl.
Is there a solution to this? Do I have to enable reflection for that type just to allow design-time attributes through?
I am aware of the rd.xml file that can be embedded in a project. However, if a <Type Name="Windows.UI.Xaml.Controls.Panel" ... /> is included, doesn't that mean that I'm telling the compiler to exclude that panel from .Net Native optimization?

This is an unfortunate bug in the version of the .Net Native tools (ilc.exe) that you're running on. This attribute is supported properly as of the Update 1 release of Visual Studio. You can get the RC here: https://www.visualstudio.com/en-us/news/vs2015-update1-vs.aspx
You can safely ignore that warning if you're stuck using older tools.

Related

Xamarin.Forms App crashes on iOS when installed via Testlfight

Hello fellow developers!
I am developing a Xamarin.Forms App for android and iOS.
It works fine in Debug and Release mode on Android Emulators, Android Devices, iOS Emulators.
But there is a problem with iOS Devices. Directly deploying the Debug/Release Builds to a device works. But when I upload the app to the AppStore and install it via Testflight on my device, it crashes on startup.
From the console I can see following errors:
"System.MissingMethodException: Default constructor not found for type App.Views.Login"
"Default constructor not found for type ColorPicker.iOS.Effects.ColorPickerTouchEffectiOS"
The first one is related to my Login View, which has a default constructor and works fine in debug and release builds.
The second one is related to a nugget package.
My question is:
Why are the default constructors available in Debug and Release but not when i download the app via Testflight? And how can I fix this?
Linking behaviour is set to "Link all".
That's because when you use the Link all assemblies option you need to manually preserve the classes in your project and potentially mark out library code that isn't linker safe.
There is a Microsoft document specifically catering to this question : https://learn.microsoft.com/en-us/xamarin/ios/deploy-test/linker?tabs=macos
You could set your linker behaviour to Link SDK assemblies only temporarily while you manually get ready for a full link.
Preservin code:
When you use the linker it can sometimes remove code that you might have called dynamically either using System.Reflection.MemberInfo.Invoke, or by exporting your methods to Objective-C using the [Export] attribute and then invoking the selector manually.
In those cases, you can instruct the linker to consider either entire classes to be used or individual members to be preserved by applying the [Xamarin.iOS.Foundation.Preserve] attribute either at the class-level or the member-level. Every member that is not statically linked by the application is subject to be removed. This attribute is hence used to mark members that are not statically referenced, but that are still needed by your application.
Skipping Assemblies
It is possible to specify assemblies that should be excluded from the linker process, while allowing other assemblies to be linked normally. This is helpful if using [Preserve] on some assemblies is impossible (e.g. 3rd party code) or as a temporary workaround for a bug.
--linkskip=NameOfAssemblyToSkipWithoutFileExtension // Single assembly
--linkskip=NameOfFirstAssembly --linkskip=NameOfSecondAssembly // Multiple Assemblies
Hope this helps. Make sure you go through the MS doc for more details

Adding Resharper code annotation to own code in a non-invasive manner

I want to flag one of my methods with the StringFormatMethod attribute so Resharper syntax highlights it.
I was able to do this by referencing the JerBrains.Annotations assembly and adding the attribute.
However I find this to be a very invasive way to do this. Not everybody here uses JetBrains and it will require committing the .dll to subversion, adding the dependency and littering the code with something that is specific to a particular IDE, which I hate.
I read about the "external annotations" feature, but I wasn't able to do it. I'm not sure if I did it wrong or if it's simply not supported for a project inside the solution (i.e not a compiled assembly reference).
So is there a way to add a code annotation to a method in the project in a non-invasive way?
P.S this is the method:
using System;
namespace MyLib
{
public static class Assert
{
public static void That(bool condition, string format, params object[] #params)
{
if (!condition)
throw new Exception(string.Format(format, #params));
}
}
}
And this is the contents of
C:\Program Files (x86)\JetBrains\ReSharper\v7.1\Bin\ExternalAnnotations\MyLib.xml:
<assembley name="MyLib">
<member name="MyLib.Assert.That(System.Boolean,System.String,System.Object[])">
<attribute ctor="M:JetBrains.Annotations.StringFormatMethodAttribute.#ctor">
<argument>format</argument>
</attribute>
</member>
</assembley>
Just to sum up possibilities:
You reference nuget Jetbrains.Annotations, and DO NOT define JETBRAINS_ANNOTATIONS:
Such annotations are useful only for developers working with source code, they are not compiled in your binary (Conditional statement is used) and they are not visible when referencing your dll. You can even add developmentOnly="true" attribute to Jetbrains.Annotations in packages.config, so by default it would not be treated as dependency.
You reference as above but define JETBRAINS_ANNOTATIONS:
now you have real binary dependency and Jetbrains.Annotations.dll must be either distributed with your library or it must be downloaded as nuget dependency.
You copy annotations with internal checked (so client code would not use them), into "YourLib.Annotations": They then embedded into your lib and available for other developers even when they use only binary version.
You provide external annotations: for bigger libraries/more attributes this can also consume 40k, it is separate file, and generally it is less trivial to create/consume.
I personally went with third option (for shared libraries, projects usually just use nugets)
You don't have to reference the assembly to add annotation attributes. As per the documentation, you can go to ReSharper/Options/Code Annotations, copy the attribute implementations to the clipboard, and paste them into your own source, where ReSharper will use them. You can even change the namespace they're in if you'd prefer not to have JetBrains in your assembly.
I don't know whether you'll have any luck using external (XML) annotations for source code, though. I get the impression they're only for existing binaries. That said, I think that decorating your source with attributes is quite valuable as a source of documentation for yourself and other developers.
Don't know if it helps, but the element name <assembley> is misspelled (unless they actually used that in the schema). Should be <assembly>.

Class Library Intellisense not showing up after adding the dll to the references

In C#, I made a ClassLibrary that has one Namespace and one Class.
I saved it and build it.
in other Projects, when i use it, I add it to my references by browsing to the .dll location.
But The Problem is that its name is not showing up in the Intellisense.
i.e when I: using ... my dll doesn't show ..
I'm Importing the library to a ConsoleApp.
both of the App and the library target Framework is .NET Framework 4.0
and I made their Assembly Version 4.0.0.0 so they're the exact same.
is there a setting or something that I'm missing ?
how can i make it pop up ?
I'm using VS2010 Professional
Thank you for your help
Maybe this be usefull, I was having a similar issue, I have a Web project, add the reference to a Class Library by selecting the project, but if I made a change on the class library, I canĀ“t see that change on the intellisense of the Web Project, after try many things, I see that in the recently added reference, the value of the option "Local Copy" was set "True", then I change it to false and everething works!
I had a similar issue but in my case it was a property on the class. If you go to the file properties and look for a Build Action. Somehow mine was set to Content it had to be set to Compile.
I am using Visual Studio 2013. I hope this helps someone else.
Is the namespace for your assembly different than the namespace for your currently open project? I've had times when the current project and an assembly share the same namespace path the intellisense can mess up.
In general, Visual Studio is pretty good about intellisense generation, especially for C#. But sometimes there are some interesting conditions regarding ambiguities, and especially mixing project types where it just doesn't quite work.
Placing your content in the same namespace makes me wonder if you've actually fixed the problem (it may just be autocompleting the namespace in the currently loaded project rather than the assembly), but if it allows you to continue working, then go with it!
Right click on project on which you add reference of your dll/project select menu project dependancies and select/MarkCheckBox for reference project/dll. then it will work fine.
If the class library project had its name changed after creation, then intellisense may fail finding it due to directory issues, I believe.
I created my class with the generic "ClassLibrary1" or whatever, and then later changed the default namespace, class name, and project name inside of VS2017. I closed VS2017 and changed the directory name to match my default namespace, and then re-associated the project file in VS2017, and then re-added the reference in my main project file.
All seems to be fixed now.

How do WPF Markup Extensions raise compile errors?

Certain markup extensions raise compile errors. For example StaticExtension (x:Static) raises a compile error if the referenced class cannot be found. Anyone know the mechanism for this? Is it baked into the XAML compiler or is such functionaility available to custom markup extensions?
EDIT: mfeingold below suggested that I need to look into the IVsErrorList interface, but I can't immediately see how that would help someone white a markup extension that generates a compile-time error. Any examples?
Extending the BAML compile process to log additional errors
I encountered this same problem last year. I was writing my own extension for which I wanted compile-time errors in certain scenrios and discovered that just throwing an exception from ProvideValue didn't work because ProvideValue isn't called until the XAML is actually loaded and the object tree is created.
I did some experiments and discovered that the compiler error message for x:Static is a byproduct of an optimization done by the the BAML compiler. The BAML format actually has a concept of a specific member of a specific type, so when the XAML contains x:Static the compiler actually replaces it with a special record that directly references the member rather than containing the type and method name. It does this by explictly recognizing the StaticExtension class. TypeExtension has a similar optimization.
I searched for hooks that would allow me to have my own code called during BAML compilation, but I didn't find any. BAML compilation is mostly just a straight transliteration into a binary format that corresponds to the XAML, with a few specific optimizations but mostly ignoring what it sees.
I ended up adding an extra step to the build process, modeling my code off of Microsoft.WinFX.targets and the other built-in targets files. This step scans the XAML for my markup extension, checks the parameters, and generates a compile error if they are not correct. This is done completely independently of the translation into BAML. It was a couple days' extra work to implement this when all was said and done, but I learned a lot.
Caveat about creating your own .targets file
If you're thinking about adding your own .targets file, you should be aware that unless you include the target in the local machine's SafeImports registry key, both Visual Studio and Expression Blend will complain that about any project that includes your .targets file. This key requires Administrator access on the machine to update. This may or may not be an issue depending on your deployment scenario. (For example, a machine-wide MSI install would fix it, or you could manually set the key if you only have a few development machines). In my case it didn't matter since I already needed the custom .targets file for some other things I was doing in that project.
Error logging from a build task
You don't need IVsErrorList to add errors to Visual Studio during a build (and if you did, you would not properly support command-line builds, Expression Blend, and other tools).
All you need to do is to call Log.LogErrror Log.LogWarning from inside your build task, like this:
public class CheckForErrorsInMyMarkupExtension : Task
{
... parameters here ...
public override Execute()
{
... code to load XAML and scan it for markup extension errors ...
... when you discover an error ...
Log.LogError("I saw an error");
}
}
There are several VisualStudio integration API which allows you to generate your own diagnostic messages from a MEF extension (VS2010 only) a VSIntegration Package or an add-in.
check out IVsErrorList interface as well as OutputTaskItemString method of the IVsOutputWindowPane interface. The latter is what I used in my django editor.
The calls to these methods of course are baked into XAML compiler - how could they not be, they are based on results of the XAML parsing

strange warning about ExtensionAttribute

I'm getting a strange warning:
The predefined type 'System.Runtime.CompilerServices.ExtensionAttribute' is defined in multiple assemblies in the global alias; using definition from 'c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll'
There is no line number given, so it's hard to figure out what it's on about.
The compiler error code is CS1685
Are you using someone's dll (or your own) which had implemented this attribute (with exactly the same name) itself as a means of using some c# 3.0 features on pre .Net 3.5 runtimes? (A common trick)
This is the probable cause. Since it is using the correct one (the MS one in the GAC) this is not a problem though you should hunt down the other and remove it.
Expanding on ShuggyCoUk's (correct) answer
Truthfully it doesn't matter which version of the attribute is used (GAC, 3rd part, etc ...). All that matters is the C#/VB compiler can find some attribute with the correct name. The attribute serves no functional purpose in code. It exists purely to tell the Compiler "hey, this is an extension method".
You can safely ignore this warning.
I agree with ShuggyCoUk that the best course of action is to try to remove the offending dll. That may not be possible, though.
Another way to resolve the ambiguity that the compiler is complaining about is to change the Alias of the referenced dll. In your project, in the References folder, if you click on a referenced dll you will see the Aliases property. By default, this is "global", which allows you to do things like "global::SomeNamespace.SomeType". You might simply be able to change the alias to something else.
This fixed a problem I had where I needed to reference Microsoft.Scripting.Core.dll, but it contained some types that conflicted with mscorlib.dll. I changed the Aliases property to be "ThirdParty" instead of "global", and that fixed the warning.
I have the same problem.
In my case the problem was the assembly Mono.Cecil.
Migrating from local references to nuget, when i add NHibernate references the package automatically adds this reference.
This reference was removed, and compiled my project again.
Remove it and be happy!!
This image was taken from ILSpy ( http://i.stack.imgur.com/Qyd5o.png )
The compiler does not know which System.Runtime.CompilerServices.ExtensionAttribute
So it is using the defination from c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll'
A .dll you are using might have the same extenstion.
I triggered this error by installing IIS with .NET 3.5 instead of 4.5 by accident.
Fix was to add 4.5 back in in "Add Features ..." in control panel.

Categories