TypeConversion icon indicating copy to clipboard operation
TypeConversion copied to clipboard

How to port code in legacy nuget package to this package TypeConversion.

Open zydjohnHotmail opened this issue 4 years ago • 4 comments

Hello: I want to port an old C# class library to target .NET 5.0 for Windows 10. The old class library used TypeConvert nuget version 2.1.6, but when I install this nuget package, I got warning for the TypeConvert nuget package is legacy. As I don’t want to use the legacy package, but I don’t quite understand how to use other nuget package or use C# built-in library like: Convert.ChangeType Method from System.Runtime.dll. Let me know if I can use this package TypeConversion (version 3.0.1) to replace TypeConvert package version 2.1.6 to replace the following C# code.

	internal static T? GetNullable<T>(string? id)
		where T : JsObject
	{
		if (id == null) { return null; }

		var (constructor, @ref) = 
			objRefs.GetOrAdd(id, _ => throw new ObjectDisposedException(id));
		
		if ([email protected](out var obj))
		{
			obj = constructor(id);
			@ref.SetTarget(obj);
		}

		return (T) TypeConvert.Convert
		(
			value: obj,
			toType: typeof(T)
		);
	}

Thanks,

zydjohnHotmail avatar Apr 05 '21 19:04 zydjohnHotmail

Hi @zydjohnHotmail ! Yes, I recently completely redesigned the package. Now, instead of the globally accessible and static type TypeConvert, there is an interface ITypeConversionProvider that can be injected into DI of you application:

using using deniszykov.TypeConversion;

private static IHostBuilder CreateHostBuilder(string[] args) =>
	Host.CreateDefaultBuilder(args)
		.ConfigureServices((context, services) =>
		{
			services.AddSingleton<ITypeConversionProvider, TypeConversionProvider>();
                        // also you could configure it
                        services.Configure<TypeConversionProviderConfiguration>(options => {});
		});

And used from any injectable context:

using using deniszykov.TypeConversion;

public static class MyController
{
    public MyController(ITypeConversionProvider conversionProvider)
    {
        object value = 1;
        var nullableIntValue = conversionProvider.Convert<object, int?>(value);
    }
}

Or you can just expose it as static member:

public static TypeConvert {
    public static readonly Default = new TypeConversionProvider();
}

This approach is not recommended because it impede testing and increases code cohesion.

deniszykov avatar Apr 06 '21 09:04 deniszykov

Hello: Actually, the code I wanted to port was not from me, it was from other's, and the code was rather complicated, I don't understand it very well. But I tried on your code: I created one C# console app, add nuget package, and copy and paste your code, it didn't get compiled. I got some errors like: CS0710 Static classes cannot have instance constructors For the following lines of code: public MyController(ITypeConversionProvider conversionProvider) { object value = 1; var nullableIntValue = conversionProvider.Convert<object, int?>(value); } The code which used your old package seems to be easier to understand: Convert object from one type to another type. But using your new package, I am totally lost which is the old type, and which is the new type. As the space here is rather limited, how I can send you more code? which I need to use your old package, it may help you understand the original type better, as the code was not from myself. Thanks,

zydjohnHotmail avatar Apr 06 '21 09:04 zydjohnHotmail

Ok, then you could use static class approach:

       // this is compatible with old package's signature
	public static class TypeConvert
	{
		public static TypeConversionProvider Default = new TypeConversionProvider();

		public static ToType Convert<FromType, ToType>(FromType value, string format = null, IFormatProvider formatProvider = null)
		{
			return Default.Convert<FromType, ToType>(value, format, formatProvider);
		}
		public static bool TryConvert<FromType, ToType>(FromType value, out ToType result, string format = null, IFormatProvider formatProvider = null)
		{
			return Default.TryConvert<FromType, ToType>(value, out result, format, formatProvider);
		}
		public static string ToString<FromType>(FromType value, string format = null, IFormatProvider formatProvider = null)
		{
			return Default.ConvertToString(value, format, formatProvider);
		}
		public static object Convert(object value, Type toType, string format = null, IFormatProvider formatProvider = null)
		{
			return Default.Convert(value?.GetType() ?? typeof(object), toType, value, format, formatProvider);
		}
		public static bool TryConvert(ref object value, Type toType, string format = null, IFormatProvider formatProvider = null)
		{
			return Default.TryConvert(value?.GetType() ?? typeof(object), toType, value, out value, format, formatProvider);
		}
		public static string ToString(object value, string format = null, IFormatProvider formatProvider = null)
		{
			return Default.ConvertToString(value, format, formatProvider);
		}
	}

or continue to use old package. It is not broken or something, just obsolete.

deniszykov avatar Apr 06 '21 09:04 deniszykov

Hi, Thanks for your reply, it will take some time to understand your code, and understand the code I want to port. But the type which has to be converted seems to be rather complicated. I will spend time to understand it better before I ask more questions.

zydjohnHotmail avatar Apr 06 '21 10:04 zydjohnHotmail