Lambda expression create unrelated compile error - c#

Whenever I add a lambda expression (in the following form) to my wpf project, I get an error. The errors are nothing to do with the expression, but they arrive every time I add one.
here is my latest:
using ( LeisureServiceClient client = ServiceFactory.Instance.GetLeisureService() )
{
client.Execute( ServiceFactory.Instance.ConnectionDetails, new MoveBasketItemsToAccountCommand()
{
BasketItemIDs = bisList.ToList().ConvertAll<Guid>( bis => bis.ID )
} );
}
This seems perfectly valid to me, this gives the following compile error, highlighting client from client.Execute(...).
Error 43: The type 'System.Windows.DependencyObject' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.
this code is nothing to do with a DependancyObject. Regardless, System.Windows is referenced in the .cs file, which also contains:
public class PointOfSaleViewModel : DependencyObject
which is quite happy to compile when the lambda expression is removed.
now, to add confusion... this is fine:
ServiceFactory.Instance.ShiftDataRefreshedEvent += ( s, e ) =>
{
Account = new ObservableCollection<BasketItemSummary>( ServiceFactory.Instance.CurrentContact.Account );
Basket = new ObservableCollection<BasketItemSummary>( ServiceFactory.Instance.Shift.OpenCurrentContact.Basket );
};
so, it's not the lambda expression itself that's causing the error, I'm out of ideas as to why this isn't compiling, and pretty keen to get some input before my head explodes.
Update
the alternate syntax suggested by a colleague
BasketItemIDs = bisList.ToList().ConvertAll( delegate( BasketItemSummary basketItem ) { return basketItem.ID; } )
also fails, giving the same compilation error.

It sounds to me like BasketItemSummary (or one of the properties) exposes this dependency on the public API - perhaps it is a base-class for the type. Simply: add the missing reference as it instructs.

I know this question is old, but in case someone else faces this problem:
Recently, I faced a problem much like yours. The solution I'm working includes a web project which has reference to a wpf project (for generating documents for downloading). After some modifications in the wpf project, the web project would not compile anymore, with the following error message:
Error 4 The type 'System.Windows.DependencyObject' is defined in an assembly that is not referenced. You must add a reference to assembly 'WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
After some debugging, I figured out the error message only pointed to lines which involved LINQ operations (first I also thought it was related to lambdas, as you).
In the end, the root of the problem were some wpf's visual tree helper methods I had taken from http://www.scottlogic.co.uk/blog/colin/2010/03/linq-to-visual-tree/. I had taken the methods from LinqToVisualTree and put them under the "System.Linq" namespace. Seemingly that was somehow conflicting with the original Linq extension methods in my web project, and once I changed the namespace of the LinqToVisualTree methods to something else the problem went away.

You need to add a reference to the dll in your project: right click on project, choose add reference.

Related

System.CommandLine Command custom validator: how to search

I am writing a C# console application project (.NET 7.0) using Visual Studio for macOS 2022 v17.4 and System.CommandLine (2.0.0-beta4.22272.1).
I am trying to add a custom validator to one of my Commands, and found the following code snippet on the project's GitHub site:
this.AddValidator(commandResult =>
{
if (commandResult.Children.Contains("one") &&
commandResult.Children.Contains("two"))
{
commandResult.ErrorMessage = "Options '--one' and '--two' cannot be used together.";
}
});
However, it will not compile in my command, due to Error CS1929: 'IReadOnlyList' does not contain a definition for 'Contains' and the best extension method overload 'MemoryExtensions.Contains(ReadOnlySpan, string)' requires a receiver of type 'ReadOnlySpan' (CS1929).
I have looked for the appropriate extension method in the various System.CommandLine namespaces, but I don't see anything. (Yes, I included the System.Linq namespace.)
Can anyone suggest what is amiss?
Edit: The original code which I "borrowed" is this:
command.AddValidator(commandResult =>
{
if (commandResult.Children.Contains("one") &&
commandResult.Children.Contains("two"))
{
return "Options '--one' and '--two' cannot be used together.";
}
return null;
});
Note that this delegate returns a value, while the updated one does not, but instead sets ErrorMessage. That's one breaking change in System.CommandLine, and it's plausible that the issue here is due to another breaking change. The System.CommandLine project does note that the project is in a state of flux and subject to changes.
I have no experience with this specific library, but peeking its source hints that the collection you are calling .Contains() on doesn't contain Strings, but rather instances of SymbolResult, hence it cannot find suitable overload for the method you are trying to call.
I couldn't find the code you provided anywhere from mentioned GitHub repo, but instead found this piece of code from this test file of library:
command.Validators.Add(commandResult =>
{
if (commandResult.Children.Any(sr => sr.Symbol is IdentifierSymbol id && id.HasAlias("--one")) &&
commandResult.Children.Any(sr => sr.Symbol is IdentifierSymbol id && id.HasAlias("--two")))
{
commandResult.ErrorMessage = "Options '--one' and '--two' cannot be used together.";
}
});
The extension method you need is defined as part of the class System.Linq.Enumerable. So you need using System.Linq; at the top of your class file.
But that won't help if your project doesn't reference the assembly System.Linq.dll. (I don't know why it wouldn't, just out of the box, but perhaps it doesn't.) So you may need to add a reference for that.

I cannot reference Microsoft.Owin.Security.AuthenticationManager, why?

I get the following error on my page:
Server Error in '/' Application.
The current type, Microsoft.Owin.Security.IAuthenticationManager, is an interface and cannot be constructed. Are you missing a type mapping?
I founded out that I should put this code in Unityconfig.cs to resolve this problem:
container.RegisterType<IAuthenticationManager>(
new InjectionFactory(
o => System.Web.HttpContext.Current.GetOwinContext().Authentication
)
);
But the problem is that the IAuthenticationManager is not visible
although I have added the Owin.Security as reference, I have the
using Microsoft.Owin.Security;
Can you please give me some hints?
Note that the interface you are trying to use (Microsoft.Owin.Security.IAuthenticationManager) isn't in Microsoft.Owin.Security.dll but is actually in Microsoft.Owin.dll. Check the two lines at the top that tell you both the namespace and the assembly. So you just need to add a reference to that assembly.
For situations like this, it's always worth checking the docs as the namespace doesn't always equate to the assembly name.

Cannot get type by full name despite this type exists and is loaded

Weird problem, I get System.TypeLoadException "Could not load type 'Color'":
using UnityEngine;
Type.GetType(typeof(Color).FullName, true);
Of course, I cannot just use typeof(Color), the code demonstrates that this type exists and is loaded and its name is correct.
typeof(Color).FullName == "UnityEngine.Color".
I also tried:
typeof(Color).Module.GetTypes().First(t => t.Name == "Color")
works fine, but
typeof(Color).Module.GetType("Color", true, false)
throws TypeLoadException. So I make a conclusion that it's not a "fully qualified name" problem but something else.
I also tried another types from UnityEngine assembly and from another 3rd-party assembly.
I checked Mono sources but related code is in C implementation and is quite difficult to comprehend quickly.
Type.FullName doesn't include the assembly - so unless the type is in either the calling assembly or mscorlib, it won't be found.
Basically, if you're trying to load a type from an arbitrary assembly there are two simple options:
Use the assembly-qualified name within Type.GetType()
Use Assembly.GetType
If you know another type in the same assembly at compile-time, it's often simplest to use:
Type type = typeof(KnownType).Assembly.GetType("Qualified.UnknownType");

Why I can't load classes from other assemblies?

In the web.config of my MVC project, I have this:
<appSettings>
<add key="MembershipRepository" value="Repo.MembershipRepository"/>
</appSettings>
I have a code like this:
var appSettings = ConfigurationManager.AppSettings;
string membershipRepositoryClassName = appSettings["MembershipRepository"];
Type membershipRepositoryType = Type.GetType(membershipRepositoryClassName);
IMembershipRepository repository = (IMembershipRepository)Activator.CreateInstance(membershipRepositoryType);
Suppose, the web application containing the web.config is in assembly Web.
The code segment I gave is in assembly Lib.
The class MembershipRepository is in assembly Repo.
Web has reference to both Lib and Repo.
Lib does not have reference to any other assemblies (Its liekly to be referenced as dll).
Repo may or may not have reference to Lib.
I get the membershipRepositoryType to be null. I understand that perhaps I need to specify the assembly in which MembershipRepository is. One way is to specify the assembly name in configuration (like this). But I think there should be some other ways. Otherwise how the other classes are loaded geting only the class name from the config file?
For instance, MembershipProvider class is loaded just fine from other assemblies.
How can I do the same. Or if I can't, why I can't?
From the MSDN Library documentation for Type.GetType(String):
typeName: The assembly-qualified name of the type to get. See AssemblyQualifiedName. If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace.
That last sentence explains why it sometimes works when you specify only the class name: If the executing code is in Repo, then you can get away with just specifying MembershipProvider. But I recommend that for clarity (and performance too), you avoid this behavior and always specify the assembly name. Alternately, if you already have a reference to the Assembly that contains your type, then you can call Assembly.GetType instead.
Nevertheless, if you truly have a scenario where you don't know which assembly contains your type, then you can search all loaded assemblies in the current AppDomain and try calling Assembly.GetType on each one:
Type type = AppDomain.CurrentDomain.GetAssemblies()
.Select(assembly => assembly.GetType(typeName))
.First(t => t != null);
What you're looking for is something like this:
var types = AppDomain.CurrentDomain.GetAssemblies().ToList()
.SelectMany( s => s.GetTypes() )
.Where( p => p.Name == membershipRepositoryClassName );
That is actually going to return a list, because a type with the same name may be declared in more than one assembly. If you are sure there is only one type, you can add .FirstOrDefault() or .Single() to the end of the chain. Use .FirstOrDefault() if you aren't sure if the type exists and want it to return null if it doesn't. Use .Single() if you are sure the type should exist is and want it to throw an exception if they type isn't found.

XamlParseException when referencing converter from different assembly

I have a XAML UserControl, which uses a converter contained in the same project.
xmlns:filter="clr-namespace:SampleModuleFilter" - namespace definition
So far so good. However, when I move the converter into another assembly and adjust the namespaces and references accordingly, I get the following exception:
XamlParseException - "Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception. The inner exception states "The method or operation is not implemented." which is just weird.
The namespace after the move into another library looks like this:
xmlns:filter="clr-namespace:SampleLibrary.Converters;assembly=SampleLibrary"
The converter resource definition is:
<filter:BoolToVisibilityConverter x:Key="boolToVisibilityConverter" />
and I use it like so:
Visibility="{Binding DisplayLabel, Converter={StaticResource ResourceKey=boolToVisibilityConverter}}"
IntelliSense can obviously see the library, since it works ok (offers the converter class after I write the namespace prefix).
Any ideas what the problem might be?
You have to reference your assembly also in the code-behind file.
If you reference the assembly only in the XAML part, the compiler returns a "failed to load xxx.dll" exception.
You have also to make a direct call to the connected assembly making something like this:
var dummy = new MyExternalAssemby.MyType();
or just this in a new line of code
new MyExternalAssemby.MyType();
without putting the result in a dummy variable.
Usually I do that in a static constructor.
I think this is a bug in the XAML interpreter because the XAML is not compiled but just "translated" in the BAML (binary XAML). So, if you reference a type in XAML without creating an "hard" reference in the code behind the NET linker ignores it at all.
HTH
Lorenzo
Instead of just:
xmlns:filter="clr-namespace:SampleModuleFilter"
Reference the assembly too
xmlns:filter="clr-namespace:SampleModuleFilter;assembly=SampleModuleFilterAssemblyName"
That should do the trick.
That is strange; we have our converters all located in a central library, and it works fine. Assuming references and namespaces are correct, the only thing I could suggest would be to clean and rebuild the two projects in question.
Is "SampleLibrary.dll" used somewhere in your code ?
I got a strange bug where referenced assemblies only used in xaml file are skipped at compile time, and do not appear in the dll dependencies.

Categories