I´m having a hard time trying to understand how Ninject´s NamedScope module should work. In my mind, each (defined)scope should be used to contextualize bindings that are "InNamedScope".
With this toy example:
void Main()
{
var kernel = new StandardKernel(new NamedScopeModule(), new ContextPreservationModule());
kernel.Bind<ParentC>().ToSelf().WithConstructorArgument("name", "Name1").DefinesNamedScope("scope1");
kernel.Bind<Intf>().ToConstant(new MyC() { ID = 1} ).InNamedScope("scope1");
kernel.Bind<ParentC>().ToSelf().WithConstructorArgument("name", "Name2").DefinesNamedScope("scope2");
kernel.Bind<Intf>().ToConstant(new MyC() { ID = 2 }).InNamedScope("scope2");
kernel.GetAll<ParentC>().Dump();
}
public class Intf
{
int ID { get; set; }
}
public class MyC : Intf
{
public int ID { get; set; }
}
public class ParentC
{
public ParentC(Intf[] c, string name)
{
this.C = c;
Name = name;
}
public string Name { get; set; }
public Intf[] C { get; set; }
}
for me, should yield something like this:
But instead, I get an exeception:
UnknownScopeException: Error activating UserQuery+Intf
The scope scope2 is not known in the current context.
what am I missing ?
In Ninject, scope is related to lifetime of objects. I see named scope more as a way of injecting the same instance into different classes, like this:
public class Parent {
public Parent(Child child, GrandChild grandChild) {}
}
public class Child {
public Child(GrandChild grandchild) {}
}
public class GrandChild {}
kernel.Bind<Parent>().ToSelf().DefinesNamedScope("scope");
kernel.Bind<GrandChild>().ToSelf().InNamedScope("scope");
kernel.Get<Parent>();
The grandChild injected into Parent is the same instance as is injected into Child.
Related
After looking at major pattern designs, I can't seem to make up my mind around the best to one to decouple classes in a big hierarchy system, specially were it concerns on avoiding injecting a Parent property in EVERY object along the way.
Some of the premises are:
A child might me removed from one parent and added to another.
Somewhere down the hierarchy, I need to access Parent of type X.
As mentioned before, I would like to avoid injecting a Parent (either by property or constructor) to it's children.
I have 1..1 and 1...N cardinalities.
The hierarchy from root to furthest leaf is quite extent.
If it was a small project, I would be fine with this (pseudo code):
public abstract class BaseObject()
{
public BaseObject Parent { get; set; }
}
public class RootObject() : BaseObject
{
public int Id { get; }
public ParentObject[] Parent { get; set; }
}
public class ParentObject() : BaseObject
{
public int Id { get; }
public ChildObject[] Parent { get; set; }
}
public class ChildObject() : BaseObject
{
public int Id { get; }
public void DoSomething()
{
//...navigate through Parent to get RootObject (or any other type in between that I might need)...
}
}
Can anyone point me out to the right direction?
All these requirements remind me graph data structure:
A child might me removed from one parent and added to another.
Somewhere down the hierarchy, I need to access Parent of type X.
As mentioned before, I would like to avoid injecting a Parent (either by property or constructor) to it's children.
I have 1..1 and 1...N cardinalities.
The hierarchy from root to furthest leaf is quite extent.
The easiest storage would be List<Node> where each node contains links to its predecessors and successors:
class Example
{
public List<Node> InitGraph()
{
var nodes = new Dictionary<string, Node>();
nodes.Add("Head", new Node("Head"));
nodes.Add("T1", new Node("T1"));
nodes.Add("T2", new Node("T2"));
// While that works, a method is nicer:
nodes.Add("C1");
// These two lines should really be factored out to a single method call
nodes["Head"].Successors.Add(nodes["T1"]);
nodes["T1"].Predecessors.Add(nodes["Head"]);
nodes["Head"].Successors.Add(nodes["T2"]);
nodes["T2"].Predecessors.Add(nodes["Head"]);
// Yes. Much nicer
nodes.Connect("Head", "C1");
nodes.Connect("T1", "C1");
nodes.Connect("T2", "C1");
var nodelist = new List<Node>(nodes.Values);
return nodelist;
}
}
and NodeHelper class:
public static class NodeHelper
{
public static void Add(this Dictionary<string, Node> dict, string nodename)
{
dict.Add(nodename, new Node(nodename));
}
public static void Connect(this Dictionary<string, Node> dict, string from, string to)
{
dict[ from ].Successors.Add(dict[ to ]);
dict[ to ].Predecessors.Add(dict[ from ]);
}
}
and Node class:
public class Node
{
public string Name { get; set; }
public int Coolness { get; set; }
public List<Node> Predecessors { get; set; }
public List<Node> Successors { get; set; }
public Node()
{
Coolness = 1;
}
public Node(string name) : this()
{
this.Name = name;
}
}
I have created a user control that contains an ObservableCollection<Something>. I learned that I cannot cast say ObservableCollection<Tiger> to ObservableCollection<Animal>. The solution I found was to add a helper class that handles all low level collection manipulation. My suspicion is that there is a more elegant solution and if so, maybe someone can point me into that direction.
See the code below that captures the problem and my solution. Zoo corresponds to the WPF UserControl. (Actually a zoo for one type od animal.) Ideally I would define it as Zoo<T> i.e. as a generic type but that would prevent me from using XAML. I need to define Animals as object in order assign to it.
class Program
{
public static void Main(string[] args)
{
Zoo zoo = new Zoo();
List<Tiger> tigers = new List<Tiger>() { new Tiger() };
zoo.Animals = tigers;
zoo.Helper = new TigerHelper(tigers);
Console.WriteLine(zoo.GetCount());
Console.ReadLine();
}
}
public class Animal { }
public class Tiger : Animal { }
public interface Helper { int GetCount(); }
public class TigerHelper : Helper
{
private List<Tiger> tigers;
public TigerHelper(List<Tiger> tigers) { this.tigers = tigers; }
public int GetCount() { return tigers.Count; }
}
public class Zoo
{
public object Animals { get; set; }
public Helper Helper { get; set; }
public int GetCount() { return Helper.GetCount(); }
}
Rather than go all the way down to object, you can use IList. This gives you access to most of the features of the list, but without the generics. For example, you can still access the Count property:
public class Zoo
{
public IList Animals { get; set; }
public Helper Helper { get; set; }
public int GetCount() { return Animals.Count; }
}
We were using service references which provided api's to access the some functions with specific types,as those service references are no more available we are planning to have similar classes to make our code work
Service references provided Service type as follows
SearchService → SearchResponse → Fields
Which I feel is a nested class was trying to build the similar class .
public class SearchResponse_t
{
public string FieldName { get; set; }
public string FieldValue { get; set; }
}
public class SearchResult_t
{
public SearchResponse_t SearchResponse { get; set; }
}
I am novice to C#
I expected that when I create a new instance of the SearchResult_t same will happen on the SearchResponse_t,but it seems that's not happening.
When a class is instantiated, its members (where you don't specify a default value) are initialized to default(T) where T is the type in question.
For reference types default(T) is always null. Classes are reference types.
For value types default(T) will provide their default value. For numeric types this is 0, etc.
So to address your specific question: I would expect SearchResponse to be null after you construct SearchResult_t. If you want it to hold a new instance of SearchResponse_t you can instruct it to do that by default:
public class SearchResult_t
{
public SearchResponse_t SearchResponse { get; set; } = new SearchResponse_t();
}
or you can add a constructor and initialize it there:
public class SearchResult_t
{
public SearchResponse_t SearchResponse { get; set; }
public SearchResult_t()
{
this.SearchResponse = new SearchResponse_t();
}
}
Alternatively, you can do it after you instantiate the class:
SearchResult_t result = new SearchResult_t();
result.SearchResponse = new SearchResponse_t();
To address your expectation that SearchResponse would also be populated with a new instance, consider the following example:
public class Node<T>
{
public Node<T> Previous { get; set; }
public Node<T> Next { get; set; }
public T Item { get; set; }
}
In this example, Node<T> references itself as Previous and Next values. If .NET were to also instantiate them, you would have an infinite loop. This isn't the only reason why things work like this, I imagine, but it's a good example of why they don't.
I believe this is what you are looking for.
public class SearchResult_t
{
private SearchResponse_t _searchResponse = new SearchResponse_t();
public SearchResponse_t SearchResponse
{
get { return this._searchResponse; }
set { this._searchResponse = value; }
}
}
I'm having some interface woes!
Here's the code:
I expected to be able to access the properties Added and ID through my test template, but intellisense says No!
Am I misusing an interface? Have I made a silly error?
Any advice appreciated - this is driving me nuts.
namespace blah.blah.blah
{
public interface ITrackedItem
{
DateTime Added { get; set; }
int ID { get; set; }
}
public class TestTemplate<ITrackedItem>
where ITrackedItem : new()
{
public SortedSet<ITrackedItem> Set { get; set; }
public void Test()
{
Set = new SortedSet<ITrackedItem>();
foreach (var item in Set)
{
// cannot access any properties here
// var ID = item.ID; <=============|
}
}
}
}
This is the problem:
public class TestTemplate<ITrackedItem>
You've declared a type parameter called ITrackedItem, which is entirely different to the ITrackedItem interface. It's not clear that your type needs to be generic at all - can you not just use
public class TestTemplate
? If you want it to be generic in a type which must implement ITrackedItem, you should use something like:
public class TestTemplate<T>
where T : ITrackedItem, new()
{
public SortedSet<T> Set { get; set; }
public void Test()
{
Set = new SortedSet<T>();
foreach (var item in Set)
{
// now you can access any properties here
//
}
}
}
I'm stuck in my inheritances bloating here:
First let me explain the premise of my problem.
My Model:
public class Person
{
[Key]
public int PersonId { get; set; }
[MaxLength(100)]
public string Name { get; set; }
}
public class SuperHero:Person
{
[MaxLength(100)]
public string SuperHeroName { get; set; }
public virtual ICollection<SuperPower> SuperPowers{ get; set; }
}
Now, I am trying to create my viewModels for my MVC website, I have those base classes that need to be inherited by all other viewmodel displaying/editing a Person/SuperHero:
public class BasePersonViewModel
{
public string Name { get; set; }
ctors()
}
public class BaseSuperHeroViewModel : BasePersonViewModel
{
public List<string> SuperPowers{ get; set; }
ctors()
}
Here is where I am stuck, I am trying to define only one ViewModel that could be used regarless of the base class and access property of Person and/or SuperHero (if the Person is a superhero). I've been pulling my hair out but so far only found a solution which i don't like:
Example:
public class SomeViewModel<T> where T : BasePersonViewModel
{
public BasePersonViewModel obj;
public DateTime BirthDate { get; set; }
public SomeViewModel(Person data) //: base(data)
{
if (data is SuperHero)
obj = new BaseSuperHeroViewModel (data);
else
obj = new BasePersonViewModel(data);
}
}
While this would work it's really not sexy to use. And on top of that, I could have another ViewModel that inherit from SomeViewModel as well.
Is there a cleaner way to achieve this?
Edit
My main goal is to be able to able to cast my SomeViewModel depending on the one of the baseclass. Let's say do something like in my Controller:
if myclass is SomeViewModel (of type SuperHero)
Exactly how you do it for Person/SuperHero db retrival/check
var data = context.Person.first(w=> w.Id==1)
if (data is SuperHero)
..
I would like this because I would like to use the same viewmodel let's say to list superhero and person, and just display slightly differently if it's a superhero
Edit 2
I was trying to avoid using the whole Model.Obj to be able to see it directly with the Model... But the more i think about it, the more I think this is not possible really... On top of that I would like to extend some other superHero specific properties in SomeViewModel (only if SomeViewModel is a superhero), that are not declared in the BaseSuperHeroModel one... Let's say in SomeViewModel I want the field 'ComesFromPlanet' only if superhero.
Edit 3
I thought about another way to do it, but it obviously creating various ViewModel.
For the most general case (all fields that are shared for all Person) I would keep my base:
public class BasePersonViewModel
{
public string Name { get; set; }
ctors()
}
I interface specific Person:
public Interface IBaseSuperHero
{
[MaxLength(100)]
public string SuperHeroName { get; set; }
public List<string> SuperPowers{ get; set; }
}
I would keep as well OtherViewModel like this:
public class SomeViewModel:BasePersonViewModel
{
Public datetime Birthdate {get;set;}
}
Then I would create a specific SomeviewModel for other Person inheritant and used interfaces to have old and new properties.
For example:
public class SomeViewModelSuperHero:SomeViewModel, IBaseSuperHero
{
public string OriginalPlanet {get;set;}
}
Is this a clean solution?
Sorry I'm sure I am not clear about this, but I try !
Thanks for your input and time.
I am trying to define only one ViewModel that could be used regarless of the base class and access property of Person and/or SuperHero (if the Person is a superhero)
Assuming you'd return default values for super-hero properties when the model is not a super-hero, you could do something like this:
public class PersonOrSuperHeroViewModel {
private Person person;
private SuperHero superHero;
public PersonOrSuperHeroViewModel(Person personOrSuperHero) {
if (personOrSuperHero is SuperHero) superHero = personOrSuperHero;
person = personOrSuperHero;
}
public IsSuperHero { get { return superHero != null; } }
... // super-hero properties only work when IsSuperHero == true
}
How about something like
public class Person {
public virtual BasePersonViewModel MainViewModel {
get { return new BasePersonViewModel(this);}
}
}
public class SuperHero : Person {
public override BasePersonViewModel MainViewModel {
get { return new BaseSuperHeroViewModel(this);}
}
}
So if all your people classes override the MainViewModel property to return the appropriate view, you don't need
public BasePersonViewModel obj;
public SomeViewModel(Person data) {
if (data is SuperHero)
obj = new BaseSuperHeroViewModel (data);
else
obj = new BasePersonViewModel(data);
}
Because you can have
public BasePersonViewModel obj;
public SomeViewModel(Person data) { obj = data.MainViewModel; }
which will work however many subclasses of person you have.