Is it possible to create objects with circular references in Unity? - unity-container

public interface IBaz { IBar bar { get; set; } }
public class Baz : IBaz
{
public IBar bar { get; set; }
public Baz(IBar bar) { this.bar = bar; }
}
public interface IBar { IBaz baz { get; set; } }
public class Bar : IBar
{
public IBaz baz { get; set; }
public Bar(IBaz baz) { this.baz = baz; }
}
class Program
{
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IBar, Bar>(new ContainerControlledLifetimeManager());
container.RegisterType<IBaz, Baz>(new ContainerControlledLifetimeManager());
//Problem 1: I get a stack-overflow, but I am using the singleton lifetime manager?
var bar = container.Resolve<IBar>();
var baz = container.Resolve<IBaz>();
//Problem 2: I want Unity to do this automatically for me. How?
bar.baz = baz; baz.bar = bar;
var result = object.ReferenceEquals(bar, baz.bar) && object.ReferenceEquals(baz, bar.baz);
}

No, not at this time. The object isn't considered "constructed" until all the properties are set, so it's not stored in the lifetime manager until after that happens. Which results in the stack overflow in this case.

Related

asp.net core does not respect case sensitivity

i have this controller method that return an array of objects
public async Task<ActionResult<List<AllClientsDataModelDb>>> GetAll()
{
var ReturnValue = new List<AllClientsDataModelDb>();
ReturnValue = await Clda.GetClients(new { cm = 1 });
return (ReturnValue);
}
here is the code of AllClientsDataModelDb class
public class AllClientsDataModelDb
{
public long IDCLIENT { get; set; }
public string CL_CODE { get; set; }
public string CL_NOM { get; set; }
public string CL_ADRESSE { get; set; }
public string CL_CODEPOS { get; set; }
public string CL_VILLE { get; set; } = null;
public int CL_ETATCOMPTE { get; set; }
public int CL_AlerteCompta { get; set; }
}
but the result of that method (in browser) does not respect the case sensitivity of the class properties
Example :
[{"idclient":1,"cL_CODE":"1","cL_NOM":"EUROPEQUIPEMENTMysql","cL_ADRESSE":"ModifSoft","cL_CODEPOS":"44","cL_VILLE":"STDENIS","cL_ETATCOMPTE":1,"cL_AlerteCompta":0},
{"idclient":2,"cL_CODE":"2","cL_NOM":"A UTOMATISMES-SERVICESzzzz","cL_ADRESSE":null,"cL_CODEPOS":"97420","cL_VILLE":"LEPORT","cL_ETATCOMPTE":1,"cL_AlerteCompta":0},
what i'm doing wrong ?
You need to create your own Json Profile Formatter by inheriting from JsonOutputFormatter.
public class PascalCaseJsonProfileFormatter : JsonOutputFormatter
{
public PascalCaseJsonProfileFormatter() : base(new JsonSerializerSettings { ContractResolver = new DefaultContractResolver() }, ArrayPool<char>.Shared)
{
SupportedMediaTypes.Clear();
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse
("application/json;profile=\"https://en.wikipedia.org/wiki/PascalCase\""));
}
}
Then modify your Startup.cs file's ConfigureServices Method like this.
services.AddMvc()
.AddMvcOptions(options =>
{
options.OutputFormatters.Add(new PascalCaseJsonProfileFormatter());
});
Try this, it should work.

How to create two foreign keys to the same table with SQLite in Xamari Form

I working in a project with Xamarin Form using C#. I'm trying to create two foreign keys to the same table, using this code:
[Table("Posts")]
public class Post
{
[PrimaryKey]
public long PostID { get; set; }
public string Name { get; set; }
public TypeEntity mode = null;
[ManyToOne(CascadeOperations = CascadeOperation.CascadeInsert)]
public TypeEntity Mode
{
get
{
return mode;
}
set
{
mode = value;
}
}
[ForeignKey(typeof(TypeEntity))]
public long ModeID { get; set; }
public TypeEntity level = null;
[ManyToOne(CascadeOperations = CascadeOperation.CascadeInsert)]
public TypeEntity Level
{
get
{
return level;
}
set
{
level = value;
}
}
[ForeignKey(typeof(TypeEntity))]
public long LevelID { get; set; }
}
[Table("Types")]
public class TypeEntity
{
[PrimaryKey]
public long TypeID { get; set; }
public string Code { get; set; }
public string Name { get; set; }
}
As you can see, the properties Mode and Level are type "TypeEntty", so I need to create the relations.
When I try to insert data, only "Mode" property is inserted ok, "Level" property stay null.
public abstract class BaseStore<T> where T : new()
{
public static SQLiteConnection sql;
public BaseStore()
{
sql = DependencyService.Get<ISQLite>().GetConnection();
Init();
}
public void Init()
{
sql.CreateTable<T>();
}
public void Insert(T entity)
{
sql.InsertWithChildren(entity);
}
}
I switched properties order, I added Level first than Mode, and Level got the value. It means, that SQLIte take only the first property to create the relation.
Does anyone know why this isn't working?
I'm working with SQLite.Net.Core-PCL 3.1.1 and SQLiteNetExtensions 2.1.0.
You have to manually specify which foreign key corresponds to each relation. To do so, pass the ForeignKey parameter in each ManyToOne attribute.
Can't test it right now, but it would probably look something like this:
[ManyToOne(ForeignKey = "ModeID", CascadeOperations = CascadeOperation.CascadeInsert)]
public TypeEntity Mode
(...)
[ManyToOne(ForeignKey = "LevelID", CascadeOperations = CascadeOperation.CascadeInsert)]
public TypeEntity Level

View Model with a List

If I construct a View Model with a List like this:
public class ProductsViewModel
{
public bool ProductBool { get; set; }
public string ProductString { get; set; }
public int ProductInteger { get; set; }
public List<Product> ProductList { get; set; }
}
it works fine. But I've seen code that constructs a similar Model like so:
public class ProductsViewModel
{
public bool ProductBool { get; set; }
public string ProductString { get; set; }
public int ProductInteger { get; set; }
public List<Product> ProductList { get; set; }
public ProductsViewModel()
{
this.ProductList = new List<Product>();
}
}
What does the extra contructor element actually do?
When you create an object of the class ProductsViewModel with the statement:
ProductsViewModel obj = new ProductsViewModel();
It automatically instantiate the ProductList. The values in obj now are:
ProductBool = false;ProductString = null;ProductInteger = 0;ProductList = new ProductList();
If you write obj.ProductList.Count() it will give 0
If you remove this constructor or the statement inside the constructor and create object of Class ProductsViewModel as created above. The values in obj will be:
ProductBool = false;ProductString = null;ProductInteger = 0;ProductList =null
If you write obj.ProductList.Count() it will give
Exception of NullReference

EF 4.1: Cannot Add Collection - Object reference not set to an instance of an object

I was told by JL herself I needed to disable lazy loading and remove virtuals from my code, so:
I. The Domain:
public class Parent
{
public int Id { get; set; }
public ICollection<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public int FK_ParentId { get; set; }
[ForeignKey("FK_ParentId")]
public Parent Parent { get; set; }
}
II. DAL:
public DataContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
III. program.cs
var clientSvc = new ClientSvcRef.ServiceClient();
var parent = new Parent();
var child = new Child {Parent = parent};
parent.Children.Add(child);
clientSvc.AddParent(parent);
The problem: Line 4 in program.cs: "Object reference not set to an instance of an object."
There are at least two ways to deal with this issue:
(1) initialize collection yourself in the constructor,
public Parent() {
Children = new List<Child>();
}
or (2) use Create() instead of new:
var p = _db.Parents.Create();
var c = _db.Children.Create();
c.Parent = p;

Problem with MEF

I have the folllowing:
private void ConfigureMEFContainer()
{
_catalog = new DirectoryCatalog(_pluginsPath);
_container = new CompositionContainer(_catalog);
}
private readonly string _pluginsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
private DirectoryCatalog _catalog;
private CompositionContainer _container;
Container is passed to another class:
var batch = new CompositionBatch();
batch.AddPart(this);
container.Compose(batch);
[ImportMany(typeof(IOnAnnotationCreatedPlugin))]
public Lazy<IOnAnnotationCreatedPlugin, IAnnotationPluginMetadata>[] OnCreatedPlugins { get; set; }
[ImportMany(typeof(IOnAnnotationCreatingPlugin))]
public Lazy<IOnAnnotationCreatingPlugin, IAnnotationPluginMetadata>[] OnCreatingPlugins { get; set; }
[ImportMany(typeof(IOnAnnotationUpdatedPlugin))]
public Lazy<IOnAnnotationUpdatedPlugin, IAnnotationPluginMetadata>[] OnUpdatedPlugins { get; set; }
[ImportMany(typeof(IOnAnnotationUpdatingPlugin))]
public Lazy<IOnAnnotationUpdatingPlugin, IAnnotationPluginMetadata>[] OnUpdatingPlugins { get; set; }
All the collections above are empty!
Any help?
I'm can't see what's wrong, but here's a blog post on how to debug this type of thing: http://blogs.msdn.com/b/dsplaisted/archive/2010/07/13/how-to-debug-and-diagnose-mef-failures.aspx
Thanks for your responses. I changed the code to the following and now it works fine. I believe, I had a problem with the custom Export Attribute and the Metadata interface. Here is the complete code in case someone else had the same problem:
public interface IAnnotationServicePluginMetadata
{
string Name { get; }
[DefaultValue(0)]
int Priority { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class AnnotationServicePluginMetadataAttribute : ExportAttribute
{
public AnnotationServicePluginMetadataAttribute()
: base(typeof(IAnnotationServicePluginMetadata))
{
}
public string Name { get; set; }
public int Priority { get; set; }
}
Using the above:
[Export(typeof(IOnAnnotationUpdatedPlugin))]
[AnnotationServicePluginMetadata(Name = "OnUpdatedPlugin", Priority = 1)]
public class OnUpdatedPlugin : IOnAnnotationUpdatedPlugin
{ }
Properties as follows:
[ImportMany(typeof(IOnAnnotationUpdatedPlugin))]
public IEnumerable<Lazy<IOnAnnotationUpdatedPlugin, IAnnotationServicePluginMetadata>> OnUpdatedPlugins { get; set; }
Hope that helps.
Regards
Have you tried the alternative:
container.ComposeParts(this);
Also, have you ensured that you've specified the type on export, e.g.
[Export(typeof(IOnAnnotationCreatedPlugin))]
Instead of simply:
[Export]
The latter will export the concrete type with a contract for the concrete type, not the interface.

Resources