I am programming a dll with a factory pattern on C#. The factory receive an enum and return an interface. Depending on the received enum it create different objects and return it encapsulated in the interface. Any class inside the factory implements the interface and its access modifier is internal, except the own interface which is public.
The problem is when i call the dll from the main project. Each object created inside the factory has different properties and do not why i can not access or modify those properties from the main. Some help?
this is the Factory call from the main.
IConfigurator config = ConfigFactory.Instance.CreateConfigurator(Model.First);
This is how the factory works (inside the dll):
public IConfigurator CreateConfigurator(Model model)
{
switch (model)
{
case Model.First:
return (First)new First(model);
case Model.Second:
return (Second)new Second(model);
case Model.Third:
return (Third)new Third(model);
}
}
First, Second and Third has different properties and i am not able to modify it from the interface object received
Thanks.
The short answer is that you're returning an interface, therefore only the properties that are part of the interface are available until you cast the object to its concrete type.
For example:
public class A : INameable
{
public string Name { get; set; }
public int Age { get; set; }
}
public class B : INameable
{
public string Name { get; set; }
public string Description { get; set; }
}
public Interface INameable
{
string Name { get; set; }
}
public Enum Selector
{
A,
B
}
So if I use a method as follows
public INameable GetINameable(Selector selector)
{
if (selector.Equals(Selctor.A))
return new A { Name = "Name A", Age = 10 };
if (selector.Equals(Selector.B))
return new B { Name = "Name B", Description = "New Instance of B"};
}
I will get an instance of INameable returned and will only be able to access the Name property as defined in the interface.
However if I need to access the other properties then I need to cast the returned object to its concrete type as follows:
// This will be an instance of INameable
var obj = GetINameable(Selector.A);
// Now cast as an instance of A
var castObj = obj as A;
// We can now access the Age property
var age = castObj.Age;
The method can have only one return type.
Instead of chossing result by enum, create different factory method / factory class for every item.
Sample:
// instead of this
public enum FactoryEnum {
VariantA,
VariantB,
VariantC
}
object Create(FactoryEnum item);
// do this
IMyInterfaceA CreateA();
IMyInterfaceB CreateB();
IMyInterfaceC CreateC();
Related
I have a third party DLL that returns objects like Customers, Orders, etc. I'll call them Your Entities. They do have a common IYourEntity interface so I can use that as a source constraint.
I want to create a generic conversion extension method to convert all these different third party entities to My Entities with some streamlined and more maintainable code.
....but I can't figure out how to make a generic extension method that will call the concrete extension method for the specific conversion of each class.
Putting some of the main aspects of my code below, but you can get a full fiddle to play with here.
Yes, I'm probably showing I'm a bit clueless on how to do this and maybe trying to combine different concepts. Any pointers much appreciated as I've been beating my head for a couple of days now and need a life line :)
public interface IYourEntity
{
int Id
{
get;
set;
}
}
public interface IConvertToMyEntity<TYourEntity, TMyEntity>
where TYourEntity : class, IYourEntity, new()
where TMyEntity : class, IMyEntity, new()
{
TMyEntity ToMyEntity(TYourEntity yourEntity);
}
public static class ExtensionMethods
{
private static IMyEntity ToMyEntity(this IYourEntity yourEntity)
{
return new MyEntity1();
}
public static List<IMyEntity> ToMyEntityList(this List<IYourEntity> lstYourEntities)
{
return lstYourEntities.ConvertAll(q => q.ToMyEntity());
}
}
public class YourEntity1 : IYourEntity, IConvertToMyEntity<YourEntity1, MyEntity1>
{
public int Id
{
get;
set;
}
public string YourEntityName
{
get;
set;
}
public MyEntity1 ToMyEntity(YourEntity1 yourEntity)
{
return new MyEntity1()
{Id = yourEntity.Id, MyEntityName = yourEntity.YourEntityName, CreatedOn = DateTime.UtcNow};
}
public List<MyEntity1> ToMyEntityList(List<YourEntity1> lstYourEntities)
{
return lstYourEntities.ConvertAll(q => ToMyEntity(q));
}
}
Since the classes implementing IYourEntity are from a third party and not under your control, you can't implement an own IConvertToMyEntity<T1, T2> interface upon these.
One way you can handle it is by overloads of such conversion (extension) methods.
There's no need for any generic T type arguments; the common IYourEntity interface suffices.
Suppose you have 3 classes implementing the IYourEntity interface;
e.g. YourCustomer, YourOrder and YourProduct.
These need to be converted to IMyEntity instances, of which you might have different concrete implementations;
e.g. a general MyEntity and a specific MyProduct.
For the conversion you set up an extension method targeting IYourEntity.
This extension method will be called to convert an IYourEntity to an IMyEntity in case a more specific overload of this extension method does not exist.
public static IMyEntity ToMyEntity(this IYourEntity target)
{
return new MyEntity { Id = target.Id, EntityName = "Fallback name" };
}
For the entities that require a custom conversion, you set up overloads of this extension method targeting those specific source class types.
Below are such ones for YourOrder and YourProduct (but not for YourCustomer).
public static IMyEntity ToMyEntity(this YourOrder target)
{
return new MyEntity { Id = target.Id, EntityName = target.OrderName.ToUpper() };
}
public static IMyEntity ToMyEntity(this YourProduct target)
{
return new MyProduct { Id = target.Id * 100, EntityName = target.ProductName };
}
Next, define the extension method to convert the list of IYourEntity instances to a list of IMyEntity instances. In the code below, the inbetween cast to dynamic enables that the appropriate ToMyEntity overload will be called.
Note that the ToMyEntity methods don't have to be extension methods, but it might be convenient to have these in place in case you need to convert a single instance instead of a list.
public static List<IMyEntity> ToMyEntities(this List<IYourEntity> target)
{
var myEntities = new List<IMyEntity>();
foreach (var yourEntity in target)
{
var myEntity = Extensions.ToMyEntity((dynamic)yourEntity);
myEntities.Add(myEntity);
}
return myEntities;
}
An example - .net fiddle
var yourEntities = new List<IYourEntity>()
{
new YourCustomer() { Id = 1 },
new YourOrder() { Id = 2, OrderName = "Order-2"},
new YourProduct() { Id = 3, ProductName = "Product-3"}
};
var myEnties = yourEntities.ToMyEntities();
myEnties.ForEach(o => Console.WriteLine("{0} - {1} ({2})",
o.Id, o.EntityName, o.GetType().Name
));
The output of the example above looks like below.
Notice how the YourCustomer instance was handled by the general IYourEntity conversion, whereas the YourOrder and YourProduct instances got a specific treatment.
1 - Fallback name (MyEntity)
2 - ORDER-2 (MyEntity)
300 - Product-3 (MyProduct)
You can change your extension method to this:
private static IMyEntity ToMyEntity(this IYourEntity yourEntity)
{
if (yourEntity is IConvertToMyEntity<IYourEntity, IMyEntity> convertible)
return convertible.ToMyEntity;
return new MyEntity1();
}
This will not work in most cases unless you also make your interface co- and contra-variant:
public interface IConvertToMyEntity<in TYourEntity, out TMyEntity>
where TYourEntity : class, IYourEntity, new()
where TMyEntity : class, IMyEntity, new()
{
TMyEntity ToMyEntity(TYourEntity yourEntity);
}
It is still not completely clear to me how you can make a third party class implements IConvertToMyEntity that easily. Assuming you did this only to show us your actual goal, you should be very careful with what you are trying to accomplish in the Main.
If you use a List<IYourEntity>, you can only use methods and properties defined in the interface, unless you know what you are doing with specific cast. The need for List<IYourEntity> or List<IMyEntity> limits a lot the implementation of a custom mapper between My classes and Your classes. Here a possible solution:
As I said, I did not change Your classes:
public interface IYourEntity
{
int Id
{
get;
set;
}
}
public class YourEntity1 : IYourEntity
{
public int Id
{
get;
set;
}
public string YourEntityName
{
get;
set;
}
}
Also My classes are very simple and do not contain any logic for the mapping. This is a debatable choice, but I generally prefer to keep conversion logic separated from the classes involved. This helps to maintain clean your code in case you have several conversion functions for the same pair of classes. By the way, here they are:
public interface IMyEntity
{
int Id
{
get;
set;
}
DateTime CreatedOn
{
get;
set;
}
}
public class MyEntity1 : IMyEntity
{
public int Id
{
get;
set;
}
public string MyEntityName
{
get;
set;
}
public DateTime CreatedOn
{
get;
set;
}
}
And this is how I designed the custom converter
public interface IMyEntityConverter
{
IMyEntity Convert(IYourEntity yourEntity);
}
public class MyEntity1Converter : IMyEntityConverter
{
public IMyEntity Convert(IYourEntity yourEntity)
{
var castedYourEntity = yourEntity as YourEntity1;
return new MyEntity1()
{
Id = castedYourEntity.Id,
MyEntityName = castedYourEntity.YourEntityName,
CreatedOn = DateTime.UtcNow
};
}
}
It is clear the lack of genericity, but you cannot do otherwise if you need an extension method on a List of generic My and Your classes. Also tried with covariant and contravariant interfaces but C# does not let you use them with this implementation.
Now the core of the solution: you need something that binds Your class to the My class with a custom converter, and all of this should be as more transparent as possible.
public class EntityAdapter<YourType, MyType>
where YourType : IYourEntity
where MyType : IMyEntity
{
protected YourType wrappedEntity;
protected IMyEntityConverter converter;
public EntityAdapter(YourType wrappedEntity, IMyEntityConverter converter)
{
this.wrappedEntity = wrappedEntity;
this.converter = converter;
}
public static implicit operator YourType(EntityAdapter<YourType, MyType> entityAdapter) => entityAdapter.wrappedEntity;
public static explicit operator MyType(EntityAdapter<YourType, MyType> entityAdapter) =>
(MyType) entityAdapter.converter.Convert(entityAdapter.wrappedEntity);
public MyType CastToMyEntityType()
{
return (MyType) this;
}
}
The pseudo-transparency here is given by the implicit cast to Your class. The advantage is that you can cast this EntityAdapter to an instance of a My class by calling CastToMyEntityType or the explicit operator overload.
The painful part is with the extension methods:
public static class EntityAdapterExtensions
{
public static List<IMyEntity> ToIMyEntityList(this List<EntityAdapter<IYourEntity, IMyEntity>> lstEntityAdapters)
{
return lstEntityAdapters.ConvertAll(e => e.CastToMyEntityType());
}
public static List<EntityAdapter<IYourEntity, IMyEntity>> ToEntityAdapterList(this List<IYourEntity> lstYourEntities)
{
return lstYourEntities.Select(e =>
{
switch (e)
{
case YourEntity1 yourEntity1:
return new EntityAdapter<IYourEntity, IMyEntity>(yourEntity1, new MyEntity1Converter());
default:
throw new NotSupportedException("You forgot to map " + e.GetType());
}
}).ToList();
}
}
The first one is pretty straightforward to understand, but the second one is definitely something that require maintenance. I gave up on generics for the reasons already explained, so the only thing left to do is to create the EntityAdapters starting from the actual entity types.
Here is the fiddle
This may be a little controversial but maybe a different way is better?
Firstly, and this is more for my sake, I would suggest more easily understandable terminology so instead of 'your' and 'my' I would use 'source' and 'dest'.
Secondly I wonder if the generics route is necessary? I'm assuming (and I may be wrong) that for each of the classes you have coming from your third-party assembly, you have a specific class for it to be converted to. So maybe this could be achieved much more easily with a constructor override in your destination class.
// third party class example
public class SourceClass
{
public int Id { get; set; }
public string Name { get; set; }
}
// the destination class in your project
public class DestClass
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreatedOn { get; set; }
// default constructor
public DestClass()
{
}
// conversion constructor
public DestClass(SourceClass source)
{
Id = source.Id;
Name = source.Name;
CreatedOn = DateTime.UtcNow;
}
}
This way you convert a single instance using:
// source being an instance of the third-party class
DestClass myInstance = new DestClass(source);
And you can convert a list with LINQ:
// source list is IList<SourceClass>
IList<DestClass> myList = sourceList.Select(s => new DestClass(s)).ToList();
If you wanted to you could implement extensions for your conversions. This again would not be generic as you'll need one for each class pairing but as it's an alternative to writing a converter class for each, it will be overall less code.
public static class SourceClassExtensions
{
public static DestClass ToDest(this SourceClass source)
=> new DestClass(source);
public static IList<DestClass> ToDest(this IList<SourceClass> source)
=> source.Select(s => new DestClass(s)).ToList();
}
If you still want something generic then you'll want a converter for each class pair, implementing a suitable interface. Then I'd recommend a converter factory class where you'll need to register the specific converters either into a dictionary in the class or via dependency injection. I can go into this further if you'd prefer but I think it would be more complicated.
sorry for writing here its not an actual answer,
there is no option for generically to do this
you have to write for every entity
public interface IConvertToMyEntity<TYourEntity, TMyEntity>
where TYourEntity : class, IYourEntity, new()
where TMyEntity : class, IMyEntity, new()
{
TMyEntity ToMyEntity(TYourEntity yourEntity);
}
I saw this code from your question.
It depends on what you want to do after transformation
you should use data mapper
public class MapProfile : Profile
{
public MapProfile()
{
CreateMap<TYourEntity , TMyEntity >();
CreateMap<TMyEntity , TYourEntity >();
}
}
Basically I have an abstract class with we'll say two properties, one being abstract and some derived classes.
public abstract class BaseClass {
public string ID { get; set; }
public abstract string Name { get; };
}
public class Class1 : BaseClass { // id would be 1
public string Name { get { return "Class1 Name"; }
}
public class Class2 : BaseClass {
public string Name { get { return "Class2 Name"; }
}
public class Class3 : BaseClass {
public string Name { get { return "Class3 Name"; }
}
Then I have a method in my data layer that returns basically a list of ID's for the base class. What I'm asking is if I can create a new instance of the DerivedClass based on what these ID's are without if or switch statements? So...
List<BaseClass> list = new List<BaseClass>();
string id = dataReader["ID"].ToString(); // say this id = 1
list.Add(new BaseClass { ID = id }); // this would be "Class1 Name" and the Class would be Class1
I know I can't create a new instance of an abstract class so the 'new BaseClass()' doesn't work, but that's the only way I know how to explain it. I've looked into making a copy or clone with Reflection, but not sure if it's actually going to do what I want. This very well might not be possible, but figured I'd ask.
How about:
switch(id) {
case "1": list.Add(new Class1());
break;
...
}
You could also use:
list.Add((BaseClass)Activator.CreateInstance("AssemblyName", "Class"+id));
see also How do I instantiate a class given its string name?
Create a dictionary that contains the types associated with their ids (which its value will be in the string property you will depend on):
Dictionary<string, Type> dictOfTypes = new Dictionary<string, Type>();
dictOfTypes.Add("1", typeof(Class1));
Then depending on the id you have you can get the item from the Dictionary and then create the instance:
string id = "1";
Type classType = dictOfTypes[id];
var instance = Activator.CreateInstance(classType);
we have an interface with a Generic Customer (gold/silver), now lets say i stored the last created cutomer somewhere (Cache/DB/etc).
how do i create a GetCustomer method that returns the type of customer.
Should i add GetCustomer to the base class or interface or elsewhere ? and how do we use GetCustomer ?
Hope that makes sense.
interface ICstomerInterface<T>
{
T MakeCustomer();
}
public abstract class BaseCustomer<T>: ICstomerInterface<T>
{
public string Type { get; set; }
public string Name { get; set; }
// methods
public abstract T MakeCustomer();
}
public class Gold : BaseCustomer<Gold>
{
public override Gold MakeCustomer()
{
var customer = new Gold
{
Type= "Gold",
Name = "Jack"
};
return customer;
}
}
public class Silver : BaseCustomer<Silver>
{
public override Silver MakeCustomer()
{
var customer = new Silver();
customer.Name = "Jones";
customer.Type = "Silver";
return customer;
}
}
The problem with you design is that MakeCustomer is an instance method of the customers. This means, that you must create a customer to be able to call MakeCustomer. In other words, this design will not work!
You have two options: Either simply initialize the customers in their respective constructors, or create a customer factory. This must be a separate class (static or not).
The generic type parameter is superfluous.
public abstract class CustomerBase
{
public CustomerBase(string name)
{
Name = name;
}
public abstract string Type { get; }
public string Name { get; }
}
public class GoldCustomer : CustomerBase
{
public GoldCustomer(string name)
: base(name)
{
}
public override string Type => "Gold";
}
public class SilverCustomer : CustomerBase
{
public SilverCustomer(string name)
: base(name)
{
}
public override string Type => "Silver";
}
The Type property can be a getter only property. It can be abstract in the base class to force concrete customer classes to implement it.
The name must be passed to the constructor to be able to assign different names to different customers.
See also Abstract factory pattern on Wikipedia.
Example:
var customers = new List<CustomerBase> {
new GoldCustomer("Frank"),
new SilverCustomer("Jack")
};
foreach (CustomerBase c in customers) {
Console.WriteLine($"{c.Name} is {c.Type}");
}
Prints:
Frank is Gold
Jack is Silver
See working example: https://dotnetfiddle.net/BiAskT
You could have an extension method to get the customer type (on a static class):
public static Type GetCustomerType<T>(this ICstomerInterface<T> _customer)
{
return typeof(T);
}
All with the intention that you don't have to make redundant code each time you create a new Customer class that implements that interface.
Your sample code doesn't contain a base type that can contain all your customers, i.e. there is no strongly-typed variable that could hold either a BaseCustomer<Gold> or a BaseCustomer<Silver>. There is no type compatibility between those two at all, no more than a Dictionary<int> can be stored as a Dictionary<string> (in fact, even worse, because there isn't covariance in your object model). Given that fact, your question makes little sense, because you'll always have to declare the type parameter to store a customer somewhere, therefore there is no need to learn the type at run time.
But let's say you want a cache that works for both. You'd introduce a non-generic base interface:
public interface ICustomer
{
Guid CustomerGuid { get; }
}
public abstract class BaseCustomer<T>: ICstomerInterface<T>, ICustomer
{
///etc....
Now you can define a cache that could hold all customers:
var cache = new Dictionary<Guid,ICustomer>();
var gold = new Gold();
cache.Add( gold.CustomerGuid, gold );
var silver = new Silver();
cache.Add( silver.CustomerGuid, silver );
Now you can retrieve any customer by its Guid:
var customer = cache[guid];
And to determine its type, just use
bool isGold = customer is Gold;
bool isSilver = customer is Silver;
Or to get a string that tells you the type:
string type = customer.GetType().Name;
It appears that you are trying to use the classic Factory Method.
Personally for simple classes, like the one you are asking about, I would add a static method on the base class, like so:
public abstract class BaseCustomer<T>: ICstomerInterface<T>
{
public static BaseCustomer<T> GetLastCustomer()
{
// Get from storage, the last customer.
}
}
That way your Create customer method is separate from your get customer method but still accessible from anywhere.
I have created an application that allows users to capture information for entities based on a pre-defined template, which I create through a web interface.
So for instance I create a template and call it "Customer Template" with several properties like First Name, Last Name, Email address and I associate a "data type" to each property, which does not strictly map to a strongly typed type.
When the user then creates a new "Customer" a html form is generated with the appropriate properties / fields, which the user can provide and save.
The data types are called "Plain Text" or "Number" or "Currency" but do not map to a data type. What would be the best approach to associate a "number" to a strongly typed int, for instance, so that when I do operations on it that it is the correct type?
The number of "types" that the users will use are finite, maybe less than 10. Would I run into problems with a switch statement? Or is there another way?
I use c#.
I would use custom attributes to identify the CLR type mapped to your Form Types as such:
public enum FieldDataTypes
{
[FormTypeMetadata(typeof(string))]
PlainText = 0,
[FormTypeMetadata(typeof(int))]
Number = 1,
[FormTypeMetadata(typeof(decimal))]
Currency = 2
}
public class FormTypeMetadataAttribute : Attribute
{
private readonly Type _baseType = typeof(object);
public FormTypeMetadataAttribute(Type baseType)
{
if (baseType == null) throw new ArgumentNullException("baseType");
_baseType = baseType;
}
public Type BaseType { get { return _baseType; } }
}
// your 'FieldData' implementation would look like this...
public class FieldData
{
public FieldDataTypes FieldType { get; set; }
public object Value { get; set; }
}
You can retrieve the FieldDataTypes' attribute using reflection.
If you're using custom types for all of your data types, why not define each as a class that derives from a common abstract parent class like FormDataType. The parent class could expose some useful methods such as primitive data type association, while derived classes can handle validation, formatting, etc.
Here's a simple example where the parent class is generic. A separate interface definition is included for cases where the generic type argument T varies or is unknown:
public interface IFormDataType
{
object Value { get; }
Type PrimitiveType { get; }
string Format();
}
public abstract class FormDataType<T> : IFormDataType
{
object IFormDataType.Value { get { return Value; } }
public Type PrimitiveType { get { return typeof(T); } }
public T Value { get; private set; }
public FormDataType(T value)
{
Value = value;
}
public abstract string Format();
public override string ToString()
{
return Format();
}
}
public class Currency : FormDataType<decimal>
{
public Currency(decimal value)
: base(value)
{
//perform any validation if necessary
}
public override string Format()
{
return Value.ToString("C");
}
public static Currency Parse(string s)
{
return new Currency(decimal.Parse(s, NumberStyles.Currency));
}
}
To improve these classes, you might implement Equals, GetHashCode, IConvertible, serialization, validation, etc.
I'm writing a TemplateEngine that will allow me to use my own markup in text based files. I'm wanting to add controls as plugins as the application matures. Currently i've got a structure like the following:
interface IControl
string Id
object Value
class Label : IControl
string Id
string Value
class Repeater : IControl
string Id
List<IControl> Value
Now you'll see the strange part right away in the Repeater class with the Value property. I was hoping that having the Value type as object in the interface would allow me the flexibility to expand the controls as i go along. The compiler doesn't like this and for good reason i guess.
Bottom line: I'm trying to get all control classes to implement the same interface but have different types for the Value property.
Does anyone have any suggestions how to accomplish this?
Note: Please don't go into suggesting things like use Spark View Engine for templating. There is a reason i'm creating extra work for myself.
Normally the Repeater would implement something different, like an IItemsControl for example.
EDIT 1
(removed for brevity)
EDIT 2
Ah okay, you can always use explicit interface implementation of course:
interface IControl
{
string Id { get; set; }
object Value { get; set; }
}
class Label : IControl
{
public string Id { get; set; }
public string Value { get; set; }
object IControl.Value
{
get { return this.Value; }
set { this.Value = (string)value; }
}
}
class Repeater : IControl
{
public string Id { get; set; }
public IList<IControl> Value { get; set; }
object IControl.Value
{
get { return this.Value; }
set { this.Value = (IList<IControl>)value; }
}
}
you could also use generics:
interface IControl<T>
{
string ID{get;set;}
T Value{get;set;}
}
class SomeControl : IControl<string>
{
public string ID{get;set}
public string Value{get;set;}
}
class SomeOtherControl : IControl<int>
{
public string ID{get;set}
public int Value{get;set;}
}
I like this better than the explicit interface idea if it's just one return value that needs to change. However, I think if you had several properties that each would return a different type, you wouldn't want to have IControl. At least, I wouldn't. In that case I would recommend the explicit interfaces.
Of course, this wouldn't work if you didn't have access to the source of IControl.
Edit: had a typo. Fixed
No, the compiler doesn't allow same name fields to be of different data types other than what is defined in the interface in derived classes.
The properties (since no fields are allowed in interface) should be implemented in the deriving classes and they need to have same data type. So, you cannot probably do it with properties without explicit declaration.
However, if you make Value to be returned by a function, then it works, but you need to check the return type because the return types should match for the function, otherwise you will get error that interface's function was not implemented.
interface IControl
{
object Value();
}
class A : IControl
{
string m_value = string.Empty;
public object Value() { return m_value; }
};
class B : IControl
{
List<IControl> m_value = new List<IControl>();
public object Value() { return m_value; }
};
....
object o = new B().Value();
if (o is List<IControl>)
MessageBox.Show("List");
[Update]
You have to be careful if explicitly defining the body of the properties. Having one name for two properties would be dangerous if implementation is not done carefully.
These two properties if contain different definition, it would be unexplainable for the final use of the interface and classes.
public IList<IControl> Value
object IControl.Value
See this example:
...
class Repeater : IControl
{
List<IControl> m_Value = new List<IControl>();
public IList<IControl> Value
{
get { return this.m_Value; }
set { this.m_Value = (IList<IControl>)value; }
}
object IControl.Value
{
get
{
return this.m_Value;
}
set
{
this.m_Value = new List<IControl>();
this.m_Value.Add(new Label());
this.m_Value.AddRange((List<IControl>)value);
}
}
}
...
Repeater b = new Repeater();
IControl i = b;
List<IControl> list = new List<IControl>();
list.Add(new Repeater());
i.Value = list;
You can observe that the list container in Repeater will have different values when data is added via IControl (because of the explicit definition of IContainer.Value).