The below code compiles with .Net Framework 4.0 but not with Silverlight 4.0.
I would appreciate if anyone could shed some light on this. Here're the error messages I'm getting:
Error 1 The best overloaded method match for 'ThinkFarAhead.Confounded.Client.Models.Consumer.SetFunctionalAreas(System.Collections.Generic.IEnumerable<ThinkFarAhead.Confounded.Client.Models.IFunctionalArea>)' has some invalid arguments c:\Hanu\SilverlightApplication1\Test.cs 64 13 SilverlightApplication1
Error 3 The best overloaded method match for 'ThinkFarAhead.Confounded.Client.Models.Consumer.SetFunctionalAreas(System.Collections.Generic.IEnumerable<ThinkFarAhead.Confounded.Client.Models.IFunctionalArea>)' has some invalid arguments c:\Hanu\SilverlightApplication1\Test.cs 65 13 SilverlightApplication1
Error 2 Argument 1: cannot convert from 'ThinkFarAhead.Confounded.Web.EntitySet<ThinkFarAhead.Confounded.Web.FunctionalArea>' to 'System.Collections.Generic.IEnumerable<ThinkFarAhead.Confounded.Client.Models.IFunctionalArea>' c:\Hanu\SilverlightApplication1\Test.cs 64 47 SilverlightApplication1
Error 4 Argument 1: cannot convert from 'ThinkFarAhead.Confounded.Web.EntitySet<ThinkFarAhead.Confounded.Web.FunctionalArea>' to 'System.Collections.Generic.IEnumerable<ThinkFarAhead.Confounded.Client.Models.IFunctionalArea>' c:\Hanu\SilverlightApplication1\Test.cs 65 47 SilverlightApplication1
What I'm trying to do:
Extend generated entities (RIA) on Silverlight (4.0) side to make multiple entities with common features share the same interface (A control needs to use multiple objects the same way. These objects are pretty much the same).
Thanks in advance.
using System;
using System.Collections;
using System.Collections.Generic;
using ThinkFarAhead.Confounded.Client.Models;
using ThinkFarAhead.Confounded.Web;
namespace ThinkFarAhead.Confounded.Web
{
public class Entity { }
public class EntitySet<T> : IEnumerable<T>, IEnumerable where T : Entity
{
List<T> list = new List<T>();
public IEnumerator<T> GetEnumerator()
{
return (IEnumerator<T>)list;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(T newone)
{
list.Add(newone);
}
}
public partial class FunctionalArea : Entity
{
public string Name { get; set; }
}
public partial class FunctionalArea : IFunctionalArea { }
}
namespace ThinkFarAhead.Confounded.Client.Models
{
public interface IFunctionalArea
{
string Name { get; set; }
}
public class Variance
{
public static EntitySet<FunctionalArea> FunctionalAreas
{
get
{
return new EntitySet<FunctionalArea>();
}
}
public static void Main()
{
var abc = new EntitySet<FunctionalArea>();
new Consumer().SetFunctionalAreas(abc);
new Consumer().SetFunctionalAreas(FunctionalAreas);
}
}
public class Consumer
{
public void SetFunctionalAreas(IEnumerable<IFunctionalArea> areas)
{
}
}
}
As Austin said in SL4 you can't just pass your collection with type IEnumerable<FunctionalArea> as parameter when your method expects a IEnumerable<IFunctionalArea>.
But if you don't want to go 'dynamic', don't forget you can still do this (using System.Linq) :
var abc = new EntitySet<FunctionalArea>();
new Consumer().SetFunctionalAreas(abc.Cast<IFunctionalArea>());
new Consumer().SetFunctionalAreas(FunctionalAreas.Cast<IFunctionalArea>());
Not quite elegant, but hey, that does the trick ;)
The BCLs in Silverlight don't have covariant/contravariant markers (IEnumerable<T> is not marked as IEnumerable<out T> as in .NET Framework, for example).
User code can use these features, it's just framework code that doesn't - a limitation of the platform today.
Related
We have a base class and derived class. When we serialize a derived class, we want only the base class to be serialized. How can we achieve this in ProtoBuf-net.
Edit: new things in v3; the following now works:
[ProtoContract(IgnoreUnknownSubTypes = true)]
public class Foo {}
which does exactly what you want here.
Currently protobuf-net is not very forgiving of unexpected types, because it really wants to be able to round-trip your data. In the 3.0 codebase, this is currently restricted to:
EF proxies, which it detects by the namespace System.Data.Entity.DynamicProxies
NHibernate proxies, which it detects as anything that implements by name NHibernate.Proxy.INHibernateProxy, NHibernate.Proxy.DynamicProxy.IProxy or NHibernate.Intercept.IFieldInterceptorAccessor
I'm open to discussing new additions that could be added to relax this - it would probably need a little discussion, but: it should be possible. Simply adding a marker interface or attribute that the library recognizes as a "ignore this type" token seems pretty reasonable! In fact, as I think about it: it would seem that we could just use [ProtoIgnore] for this, by extending the AttributeTargets for ProtoContractAttribute, and adding a few lines to DynamicStub.ResolveProxies.
Right now, the following "works" (for limited values of "works"), with outputs:
Trying BaseType...
Success; got BaseType
Trying KnownSubTypeViaInclude...
Success; got KnownSubTypeViaInclude
Trying UnknownSubType...
Unexpected sub-type: UnknownSubType
Trying LooksLikeEFProxy...
Success; got BaseType
Trying LooksLikeNHibernateProxy...
Success; got BaseType
code:
using ProtoBuf;
using System;
static class P
{
static void Main()
{
// works, trivially
Try<BaseType>();
// works, processes sub-type
Try<KnownSubTypeViaInclude>();
// fails, unexpected
Try<UnknownSubType>();
// works, processes base type only
Try<System.Data.Entity.DynamicProxies.LooksLikeEFProxy>();
Try<LooksLikeNHibernateProxy>();
}
static void Try<T>() where T : BaseType, new()
{
Console.WriteLine($"Trying {typeof(T).Name}...");
try
{
var clone = Serializer.DeepClone<BaseType>(new T());
Console.WriteLine($"Success; got {clone.GetType().Name}");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
[ProtoContract]
[ProtoInclude(42, typeof(KnownSubTypeViaInclude))]
public class BaseType
{
}
public class KnownSubTypeViaInclude : BaseType { }
public class UnknownSubType : BaseType { }
public class LooksLikeNHibernateProxy : BaseType, NHibernate.Proxy.INHibernateProxy { }
namespace System.Data.Entity.DynamicProxies
{
public class LooksLikeEFProxy : BaseType { }
}
namespace NHibernate.Proxy // let's pretent to be NHibernate
{
public interface INHibernateProxy { }
}
Edit: The problem was with Nancy. Protobuf-net (de)serializes marked private fields just fine.
I am running a NetCore 2.0 unit test project. Protobuf-net appears to be ignored private fields even though the have the [ProtoMember] attribute.
[ProtoContract]
internal class Model
{
[ProtoMember(1)]
public int Example { get; private set; } // Works
[ProtoMember(2)]
private List<int> _a; // Not deserialized unless made public
public IEnumerable<int> A => this._a;
public Model(int example, IEnumerable<int> a)
{
this.Example = example;
this._a = a.ToList(); // Copy prevents mutation
}
private Model() // For deserialization
{
}
}
I have used a public IEnumerable<int> to avoid mutability and hide implementation details. It is backed by a private List<int> to allow serialization. However, protobuf-net will only deserialize the field if I make it public. The serialization, on the other hand, will actually include the data even if the field is private.
Is this intended behavior? Is there are a clean way to make protobuf-net honor the marked private field when deserializing?
P.S. The same behavior is seen for non-collection members, but I have demonstrated with IEnumerable/List because it shows the reason for this approach.
The following works identically (apart from the first line of the output) when targetting netcoreapp2.0 or net45. I'd be happy to help, but I'd need to see an example that fails. I'm using:
<PackageReference Include="protobuf-net" Version="2.3.6" />
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using ProtoBuf;
[ProtoContract]
internal class Model
{
[ProtoMember(1)]
public int Example { get; private set; } // Works
[ProtoMember(2)]
private List<int> _a; // Not deserialized unless made public
public IEnumerable<int> A => this._a;
public Model(int example, IEnumerable<int> a)
{
this.Example = example;
this._a = a.ToList(); // Copy prevents mutation
}
private Model() // For deserialization
{
}
}
static class Program
{
static void Main()
{
#if NETCOREAPP2_0
Console.WriteLine(".NET Core 2.0");
#elif NET45
Console.WriteLine(".NET 4.5");
#endif
var obj = new Model(123, new int[] { 4, 5, 6 });
var clone = Serializer.DeepClone(obj);
Console.WriteLine(clone.Example);
foreach (var val in clone.A)
{
Console.WriteLine(val);
}
}
}
I am trying to use the new ASP.NET 5 dependency injection system, but it seems limited to ONLY constructors of classes that inherit from Controller.
Is there any other way to inject things? Properties? Anything? This is so severely limiting and has had me brickwalling for days.
Just tested this (RC1 Update1), it works with other classes as well.
I wrote a small example, first the type declarations:
public interface IBaseServiceType { }
public interface IComposedServiceType
{
IBaseServiceType baseService { get; }
}
public class BaseServiceImplementation : IBaseServiceType { }
public class ComposedServiceImplementation : IComposedServiceType
{
public IBaseServiceType baseService { private set; get; }
public ComposedServiceImplementation(IBaseServiceType baseService)
{
this.baseService = baseService;
}
}
The configuration:
services.AddTransient(typeof(IBaseServiceType), typeof(BaseServiceImplementation));
services.AddTransient(typeof(IComposedServiceType), typeof(ComposedServiceImplementation));
And create the instance like this where context is your HttpContext:
var composedServiceInstance = context.ApplicationServices.GetService<IComposedServiceType>();
Register your class as a service and treat it like you would all other services
see
Net Core Dependency Injection for Non-Controller
Just wanted to know if there is a way bind a type and resolve a collection. I dont know if Ninject can do this out of the box. I'm using MVC4 with Ninject3 so I have the NinjectWebCommon.cs where I register the services. There is nowhere I can get the kernel (I read that it was bad practice to access the kernel from elsewhere, but that can certainly be the solution to this).
For example, I'm having this class:
public class CacheManager
{
public IEnumerable<SelectListItem> Get<T>() where T : INameValue
I want to be able to send
CacheManager.Get<City>
and obtain the CityRepository class.
Is it this you want to do? :
using System.Collections.Generic;
using System.Linq;
using Ninject;
using Ninject.Modules;
using Ninject.Syntax;
public class Temp
{
public interface ICity { }
public class SelectListItem
{
}
public class FooCity : SelectListItem, ICity { }
public class BarCity : SelectListItem, ICity {}
public class CityModule : NinjectModule
{
public override void Load()
{
this.Bind<ICity>().To<FooCity>();
this.Bind<ICity>().To<BarCity>();
}
}
public class CacheManager
{
private readonly IResolutionRoot resolutionRoot;
public CacheManager(IResolutionRoot resolutionRoot)
{
this.resolutionRoot = resolutionRoot;
}
public IEnumerable<SelectListItem> Get<T>()
{
return this.resolutionRoot.GetAll<T>().OfType<SelectListItem>();
}
}
}
I'm unclear as to whether you have multiple implementations of T (ICity) or one implementation but several instances (like retrieving a list of city names from the database and creating one instance per name). The later you could solve by a this.Bind>().ToProvider(...) binding.
I ended up doing:
In NinjectWebCommon.cs:
kernel.Bind(typeof(CacheManager))
.ToSelf()
.InSingletonScope();
kernel.Bind<IDataListRepository<Locale>>()
.To<LocaleRepository>();
In CacheManager.cs:
public class CacheManager: IDisposable
{
private IKernel kernel;
public CacheManager(IKernel kernel)
{
this.kernel = kernel;
}
public IEnumerable<T> GetAsEnumerable<T>()
{
var rep = kernel.Get<IDataListRepository<T>>();
return rep.GetAll();
}
I don't know if this is bad-practice (since kernel in theory should only be used in the initialization phase), but I didn't find any other way to do it.
If better options exist, please let me know.
Good afternoon everyone,
I am trying to use the example "Aspect Oriented Programming Using C# and PostSharp" by Reza Ahmadi
http://www.codeproject.com/Articles/337564/Aspect-Oriented-Programming-Using-Csharp-and-PostS and dnrTV http://dnrtv.com/dnrtvplayer/player.aspx?ShowNum=0190 for the exception handling. Everything works great if the "OnExceptionAspect" is in the same project/assembly, however the event does not work if it I move the class to it own dll.
[assembly: ExceptionAspect (AttributePriority = 1)]
[assembly: ExceptionAspect(AttributePriority = 2, AttributeExclude = true, AttributeTargetTypes = "HpsErp.Common.AspectObject.*")]
namespace AspectObject
[Serializable]
public class ExceptionAspect : OnExceptionAspect
{
public override void OnException(MethodExecutionArgs args)
{
Trace.TraceError("{0} in {1}.{2}",
args.Exception.GetType().Name,
args.Method.DeclaringType.FullName,
args.Method.Name);
if (args.Instance != null)
{
Trace.TraceInformation("this={0}", args.Instance);
}
foreach (ParameterInfo parameter in args.Method.GetParameters())
{
Trace.TraceInformation("{0}={1}", parameter.Name,
args.Arguments[parameter.Position] ?? "null");
}
}
I also created a class in the external dll for "Timing" and it works great if I add a custom attribute to the class.
namespace AspectObject
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method)]
public class TimingAspect : OnMethodBoundaryAspect
{
[NonSerialized]
Stopwatch _StopWatch;
public override void OnEntry(MethodExecutionArgs args)
{
_StopWatch = Stopwatch.StartNew();
base.OnEntry(args);
}
public override void OnExit(MethodExecutionArgs args)
{
Console.WriteLine(string.Format("[{0}] took {1}ms to execute",
new StackTrace().GetFrame(1).GetMethod().Name,
_StopWatch.ElapsedMilliseconds));
base.OnExit(args);
}
Using AspectObject;
namespace MyApp
{
public class Car
{
[TimingAspect]
private void Drive()
{
//...
}
}
}
In the end, I am hoping to have this is multi dlls so that I can reuse it ie: wcf.
Thanks for any and all help...
James
You can access your aspects if they are stored in a separate DLL.
I always create a DLL class project called Aspects. In the projects I want AOP, I add a reference to that dll class. Then decorate your methods/class/assembly like you normally do.
https://github.com/sharpcrafters/PostSharp-Toolkits <-- good examples
http://researchaholic.com/tag/postsharp/ <-- some more examples, just uploaded an example