MEF - Migration from .NET 3.5 to .NET 4.0 - mef

I've got an easy sample from the internet that works fine in the .NET 3.5 framework using System.ComponentModel.Composition.dll version v2.0.50727
I've changed the project definition and changed the target to .NET 4.0 and it works perfect.
When I replace the v2.0.50727 version of the above .dll to the latest version which is v4.0.30319 I get an error that complains during the composition of the container. The code where it break is as follows:
private void LoadPlugins() {
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
container.ExportsChanging += new EventHandler(container_ExportsChanging);
var batch = new CompositionBatch();
batch.AddPart(this);
container.Compose(batch); // throws Exception
}
And the exception is the following:
System.ComponentModel.Composition.ChangeRejectedException was unhandled
Message=The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.
1) More than one export was found that matches the constraint '((exportDefinition.ContractName == "MefTutorial.IPlugin") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "MefTutorial.IPlugin".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))'.
Resulting in: Cannot set import 'MefTutorial.PluginConsumer._myPlugins (ContractName="MefTutorial.IPlugin")' on part 'MefTutorial.PluginConsumer'.
Element: MefTutorial.PluginConsumer._myPlugins (ContractName="MefTutorial.IPlugin") --> MefTutorial.PluginConsumer
What do I need to do to migrate to the .NET 4.0 concerning MEF?

Could it be that another project still references the .net 3.5 version? The error message says that there are two exports of type IPlugin, which I'm quite certain of means that finds both the 3.5 and 4.0 version of the dll.
Check that only the 4.0 version of MefTutorial is referenced and/or present.

OK, I found the problem. Apparently in the previous version the notation was as mentioned in my previous comment, but in the new .NET 4.0 version the syntax for import should be:
code>
[ImportMany(typeof(IPlugin))]
internal List _myPlugins { get; set; }
Notice the use of List and ImportMany instead of IList and Import.

Related

ESType error when ModelDrivenControllerBase is using to call MDrivenEcoSpaceAndModelForNetStandard

a code MyController:ModelDrivenControllerBase<EcoProject1EcoSpace> in the mvc or webapi netcore project shows a error "the type 'MDrivenTemplateProj.EcoProject1EcoSpace' cannot be used as type parameter 'ESType' in the generic type or method 'ModelDrivenControllerBase<ESType>'. There is no implicit reference conversion from 'MDrivenTemplateProj.EcoProject1EcoSpace' to 'Eco.Handles.DefaultEcospace" + annoying request to add ref to the 'MDriven.Handles.netStandard, version=7.0.0.0, culture=neutral, publickeytoken=null'. (always version 7.0.0.0!)
Could you please advise how to avoid such kind of errors?
I'm trying to develop the webapi netcore 3.1 app that has ref to MDrivenEcoSpaceAndModelForNetStandard project using the NetFramework 4.x. experience.
Seems that is it wrong way for the netcore project.
Thank you!
Brand new MDriven packages on nuget targeting .netStandard2.1 and .net5 available now.
They have correct build version numbers, and are more granular in packages than the old Eco package.
https://wiki.mdriven.net/index.php/MVC
https://www.nuget.org/packages?q=MDriven*
Old style still valid:
ref to the MDrivenEcoSpaceAndModelForNetStandard project in your netcore webapi
leave ControllerBase as a base class for your MVC controller
create and activate new ecospace in the constructor of your controller
_es = new MDrivenTemplateProj.EcoProject1EcoSpace();_es.Active = true;
you can call CreateFromViewModel method if you want to use VMs, ex.
var vmc = Eco.ViewModel.Runtime.ViewModelHelper.CreateFromViewModel("SampleViewModel", this._es, null, false);
Manual fixes that are still required in MDrivenEcoSpaceAndModelForNetStandard project:
EcoProject1EcoSpace.Designer.cs - this.persistenceMapperSharer1.MapperProviderTypeName auto generated value is incorrect
EcoProject1PMP.Designer.cs - this.EcoSpaceTypeName auto generated value is incorrect
be ready that your build in VS EcoProject modeller will not be able to start persistence after the fixes above. It will show you "No suitable constructor found" message

Can't create SqlParameter in EF Core 3.1.2 in Xamarin.Android application

I have Android Xamarin.Forms project. It depends on Db project with EF Core code (SQL Server) and targeted .Net Standard 2.0. Both projects in one solution.
With EF Core 2.2.6 everything works fine. When I switch to EF Core 3.1.2, the project does not work anymore.
I made the following changes to compile it:
I added Microsoft.Data.SqlClient 1.1.1 nuget project reference and use namespace Microsoft.Data.SqlClient instead of System.Data.SqlClient
Replace DbSet<Entitiy>.FromSql calls with DbSet<Entitiy>.FromSqlRaw
When I create SqlParameter and try to access it I get an error.
E.g. when I run the following code:
try
{
var sqlParam = new SqlParameter("aaa", "bbb");
var value = sqlParam.Value; // exception thrown here
}
catch (Exception ex)
{
Debug.WriteLine($"Exception: {ex.GetType()}");
Debug.WriteLine($"Message: {ex.Message}");
Debug.WriteLine($"StackTrace: {ex.StackTrace}");
}
I get the following error messages:
Exception: System.NullReferenceException
Message: Object reference not set to an instance of an object
StackTrace: at Microsoft.Data.SqlClient.SqlParameter.get_Value () [0x00000] in E:\SqlClientInternal\agent-1_work\5\s\src\Microsoft.Data.SqlClient
etcore\ref\Microsoft.Data.SqlClient.cs:1222
at [0x00012] in .cs:100
When the sqlParam just assigned, and I want to view its value, I get the following view in Visual Studio:
I use Visual Studio 2019, I tried 16.3.4 and the latest as for now 16.4.6.
How to fix this issue? What is wrong with my code?

Upgrading EF in pregenerated views: The default target Entity Framework version requires the edmx schema version 2 or lower

I have pre-generated views following the templates of the next link:
http://blogs.msdn.com/b/adonet/archive/2008/06/20/how-to-use-a-t4-template-for-view-generation.aspx
I need to improve to Entity Framework 5.0 but if I replace the schemas as following:
stringBuilder.Replace("http://schemas.microsoft.com/ado/2008/09/mapping/cs", "http://schemas.microsoft.com/ado/2009/11/mapping/cs");
stringBuilder.Replace("http://schemas.microsoft.com/ado/2008/09/edm", "http://schemas.microsoft.com/ado/2009/11/edm");
stringBuilder.Replace("http://schemas.microsoft.com/ado/2008/10/edmx","http://schemas.microsoft.com/ado/2009/11/edmx");
stringBuilder.Replace("http://schemas.microsoft.com/ado/2009/02/edm/ssdl", "http://schemas.microsoft.com/ado/2009/11/edm/ssdl");
I still having the following error:
Warning 3 The default target Entity Framework version requires the
edmx schema version 2.0.0.0 or lower. The specified schema is version
3.0.0.0. To avoid this warning specify the target Entity Framework version explicitly. You can do this by using the EdmGen.exe
command-line tool with the targetVersion option, or by including the
targetEntityFrameworkVersion parameter when calling the GenerateCode
method.
Any idea of how to solve this issue using templates?
What is the equivalent of adding /targetversion:4.5 to EdmGen using templates?
I found the solution to my problem...
There was a leading help in the following link:
http://blog.3d-logic.com/2012/05/28/entity-framework-code-first-and-pre-generated-views/
moozzyk says:
August 5, 2012 at 11:51 pm
I did see this when using Visual Studio 2012 and EF5. For now the workaround is to edit the >template. Change the line 70 from:
var errors = viewGenerator.GenerateViews(mappingItemCollection, writer).ToList();
to:
var errors = viewGenerator.GenerateViews(mappingItemCollection, writer, >EntityFrameworkVersions.Version3).ToList();
Sorry for the inconvenience.
I had to slighlty modify my code in a similar way, from:
IList errors = viewGenerator.GenerateViews(mappingItems, writer);
To:
IList errors = viewGenerator.GenerateViews(mappingItems, writer, EntityFrameworkVersions.Version3);
After that, no warning nor error whatsoever.

Restlet proxy generation fails with latest GWT 2.5.0-RC1

Upgraded to GWT 2.5.0-RC1 and the proxy generation for Restlet breaks - I have the latest release 2.1-RC6 in my project. This is the stack trace :
java.lang.NoSuchMethodException: com.google.gwt.user.rebind.rpc.SerializableTypeOracleBuilder.<init>(com.google.gwt.core.ext.TreeLogger, com.google.gwt.core.ext.PropertyOracle, com.google.gwt.core.ext.typeinfo.TypeOracle)
at java.lang.Class.getConstructor0(Class.java:2706)
at java.lang.Class.getDeclaredConstructor(Class.java:1985)
at org.restlet.rebind.ClientProxyGenerator.getSerializableTypeOracleBuilder2_2(ClientProxyGenerator.java:767)
at org.restlet.rebind.ClientProxyGenerator.generateSerializers(ClientProxyGenerator.java:569)
at org.restlet.rebind.ClientProxyGenerator.generateProxy(ClientProxyGenerator.java:500)
at org.restlet.rebind.ClientProxyGenerator.generate(ClientProxyGenerator.java:242)
The actual exception gets thrown here :
private SerializableTypeOracleBuilder getSerializableTypeOracleBuilder2_2()
throws Exception {
SerializableTypeOracleBuilder result = null;
Constructor<SerializableTypeOracleBuilder> c = null;
c = SerializableTypeOracleBuilder.class.getDeclaredConstructor(
TreeLogger.class, PropertyOracle.class, TypeOracle.class);
result = c.newInstance(getLogger(), getContext().getPropertyOracle(),
getTypeOracle());
return result;
}
This following call seems problematic, though I do not see why :
c = SerializableTypeOracleBuilder.class.getDeclaredConstructor(
TreeLogger.class, PropertyOracle.class, TypeOracle.class);
Somebody got Restlet GWT working with the latest GWT 2.5.0-rc1 ??
UPDATE: issue opened #647
I just checked the POMs for the following GWT versions of Restlet:
http://maven.restlet.org/org/restlet/gwt/org.restlet/2.2-SNAPSHOT/
http://maven.restlet.org/org/restlet/gwt/org.restlet/2.1.1/
and they all have dependencies on version 2.2 of GWT.
That's the problem when using internal classes: SerializableTypeOracleBuilder's constructor no longer takes a TypeOracle argument, but a GeneratorContext.
http://code.google.com/p/google-web-toolkit/source/browse/releases/2.5/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java#782
That was already the case in GWT 2.4 though (with the experimental GeneratorContextExt instead): http://code.google.com/p/google-web-toolkit/source/browse/releases/2.4/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java#747
and even GWT 2.3: http://code.google.com/p/google-web-toolkit/source/browse/releases/2.3/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java#763
In other words, Restlet still depends on a 18 months old version, namely GWT 2.2: http://code.google.com/p/google-web-toolkit/source/browse/releases/2.2/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java#757
Thanks for reporting this issue. The 2.1 and master branches have been updated.

Determine version of Entity Framework I am using?

I believe there are two versions 1 and 2? And version 2 is referred to as Entity Framework 4.0?
How can I tell what version is being used in an application?
This is in my web.config does this mean I am using version 2?
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
Another way to get the EF version you are using is to open the Package Manager Console (PMC) in Visual Studio and type Get-Package at the prompt. The first line with be for EntityFramework and list the version the project has installed.
PM> Get-Package
Id Version Description/Release Notes
-- ------- -------------------------
EntityFramework 5.0.0 Entity Framework is Microsoft's recommended data access technology for new applications.
jQuery 1.7.1.1 jQuery is a new kind of JavaScript Library....
It displays much more and you may have to scroll back up to find the EF line, but this is the easiest way I know of to find out.
There are two versions: 1 and 4. EFv4 is part of .net 4.0, and EFv1 is part of .net 3.5 SP1.
Yes, the config setting above points to EFv4 / .net 4.0.
EDIT
If you open the references folder and locate system.data.entity, click the item, then check the runtime version number in the Properties explorer, you will see the sub version as well. Mine for instance shows runtime version v4.0.30319 with the Version property showing 4.0.0.0. The EntityFramework.dll can be viewed in this fashion also. Only the Version will be 4.1.0.0 and the Runtime version will be v4.0.30319 which specifies it is a .NET 4 component. Alternatively, you can open the file location as listed in the Path property and right-click the component in question, choose properties, then choose the details tab and view the product version.
can check it in packages.config file.
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="6.0.2" targetFramework="net40-Client" />
</packages>
if you are using EF core this command below could help
dotnet ef --version
To answer the first part of your question: Microsoft published their Entity Framework version history here.
If you open the references folder and locate system.data.entity, click the item, then check the runtime version number in the Properties explorer, you will see the sub version as well. Mine for instance shows v4.0.30319 with the Version property showing 4.0.0.0.
If you go to references, click on the Entity Framework, view properties It will tell you the version number.
internal static string GetEntityFrameworkVersion()
{
var version = "";
var assemblies = System.AppDomain.CurrentDomain.GetAssemblies().Select(x => x.FullName).ToList();
foreach(var asm in assemblies)
{
var fragments = asm.Split(new char[] { ',', '{', '}' }, StringSplitOptions.RemoveEmptyEntries).Select(x=> x.Trim()).ToList();
if(string.Compare(fragments[0], EntityFramework, true)==0)
{
var subfragments = fragments[1].Split(new char[] { '='}, StringSplitOptions.RemoveEmptyEntries);
version =subfragments[1];
break;
}
}
return version;
}
In Solution Explorer Under Project
Click on Dependencies->NuGet->Microsoft.NetCore.All-> Here list of all Microsoft .NetCore pakcages will appear. Search for Microsoft.EntityFrameworkCore(2.0.3) in bracket version can be seen
Like this
After finding package
For .NET Core, this is how I'll know the version of EntityFramework that I'm using. Let's assume that the name of my project is DemoApi, I have the following at my disposal:
I'll open the DemoApi.csproj file and take a look at the package reference, and there I'll get to see the version of EntityFramework that I'm using.
Open up Command Prompt, Powershell or Terminal as the case maybe, change the directory to DemoApi and then enter this command: 👉🏻
dotnet list DemoApi.csproj package