How to separate levels of abstractions w/ Interfaces? - oop

I'm automation the warehouse and I'm trying to create the domain model for next task:
A warehouse has a lot of products. Products can be either liquid, or grocery, or piece by piece. There are two packing lines in the warehouse to pack either liquid products or all other products. Piece by piece products does not require packing.
Here are my models:
enum ProductType
{
Liquid,
Grossery
}
interface IProduct
{
ProductType ProductType { get; }
}
interface IPackedProduct : IProduct
{
bool IsPacked { get; }
}
interface ILiquidProduct : IProduct
{
}
interface IGrosseryProduct : IProduct
{
}
interface IPackingLine
{
IPackedProduct Pack(IProduct product);
}
interface IGrosseryPackingLine : IPackingLine
{
IPackedProduct Pack(IGrosseryProduct p);
}
class ProductPackingLine : IPackingLine
{
public IPackedProduct Pack(IProduct product)
{
Console.WriteLine("Packing {0} default packing line", product);
return new PackedProduct(product);
}
}
class LiquidsPackingLine : IPackingLine
{
public IPackedProduct Pack(ILiquidProduct product) // I want this <=======================
{
Console.WriteLine("Packing {0} by liquid packing line", product);
return new PackedProduct(product);
}
}
class GrosseryPackingLine : IPackingLine
{
public IPackedProduct Pack(IProduct product)
{
Console.WriteLine("Packing {0} by grossery packing line", product);
return new PackedProduct(product);
}
}
I'm using it like this:
IProduct milk = new LiquidProduct(ProductType.Liquid);
IProduct pasta = new GrosseryProduct(ProductType.Grossery);
var packer = new PackingManager();
IPackedProduct packedMilk = packer.Pack(milk);
IPackedProduct packedPasta = packer.Pack(pasta);
Here is the PackingManager
class PackingManager
{
public IPackedProduct Pack(IProduct product)
{
IPackingLine pl = GetPackingLineByProduct(product);
return pl.Pack(product);
}
private IPackingLine GetPackingLineByProduct(IProduct product)
{
switch (product.ProductType)
{
case ProductType.Liquid:
return new LiquidsPackingLine();
case ProductType.Grossery:
return new GrosseryPackingLine();
default:
throw new InvalidOperationException();
}
}
}
The problem is that if I'll use IPackingLine.Pack(IProduct p) I can pass an object of ILiquidProduct by mistake to a wrong packing line. But I need all my packing lines to implement IPackingLine to be able to use them in a more common way.
How to avoid that?

I think there are 3 main ways to solve your problem:
Work with IProduct everywhere and drop compile-time type safety in favor of runtime checks. If you go down that road then you should at least make it explicit that an IPackingLine may reject to pack a product.
E.g.
public interface IPackingLine {
IPackedProduct pack(IProduct product);
bool canPack(IProduct);
}
Use some kind of double-dispatch (the dynamic keyword with overloaded methods makes this easier in C#):
public interface IPacker {
IPackedProduct pack(IProduct product);
IPackedProduct packLiquid(ILiquidProduct product);
IPackedProduct packGrossery(IGrosseryProduct product);
}
public interface IProduct {
IPackedProduct packWith(IPacker packer)
}
class LiquidProduct implements IProduct {
IPackedProduct packWith(IPacker packer) {
return packer.packLiquid(this);
}
}
//...
If possible, introduce new abstractions that would allow a packing line to treat any kind of product the same way. For instance, imagine you had to build an application that paints squares and triangles. You could have a specialized painter for each, but you could also have a single painter that works with abstract shapes. E.g. painter.paint(triangle.getShape()).

Related

How can I validate different types within a collection using FluentValidation?

I have a class with a collection that needs validation. The generic on the collection takes an interface and different types can be added to the collection.
What is the cleanest path forward to creating a FluentValidation validator that supports polymorphism?
public interface IWizardStep {}
public class WizardOne : IWizardStep
{
public string Model { get; set; }
}
public class WizardTwo : IWizardStep
{
public string FirstName { get; set; }
}
public class Wizard
{
public Wizard()
{
var w1 = new WizardOne();
var w2 = new WizardTwo();
Steps = new List<IWizardStep>
{
w1,
w2
};
}
public IList<IWizardStep> Steps { get; set; }
}
public class WizardValidator : AbstractValidator<Wizard>
{
public WizardValidator()
{
RuleFor(x => x.Steps)
// Steps First where is WizardOne
// Model.NotEmpty()
// Steps First where is WizardTwo
// FirstName.NotEmpty()
}
FluentValidation doesn't support polymorphism for child collections like this out of the box, but you can add this behaviour by using a custom property validator, or by using OfType in your rule definitions.
I've written about both approaches before here:
Step 1: Create a validator for each implementor
Start by creating a validator for WizardOne and WizardTwo:
public class WizardOneValidator : AbstractValidator<WizardOne> {
public WizardOneValidator() {
RuleFor(x => x.Model).NotEmpty();
}
}
public class WizardTwoValidator : AbstractValidator<WizardTwo> {
public WizardTwoValidator() {
RuleFor(x => x.FirstName).NotEmpty();
}
}
Step 2: Create the parent validator
You have two options for defining the parent validator. The simplest approach is to use OfType, but this is less performant. The more complex option is to use a custom property validator.
Option 1: Using OfType
public WizardValidator : AbstractValidator<Wizard> {
public WizardValidator() {
RuleForEach(x => x.Steps.OfType<WizardOne>()).SetValidator(new WizardOneValidator());
RuleForEach(x => x.Steps.OfType<WizardTwo>()).SetValidator(new WizardTwoValidator());
}
}
This is the simplest approach, but calling OfType inside the call RuleFor will end up bypassing FluentValidation's expression cache, which is a potential performance hit. It also iterates the collection multiple. This may or may not be an issue for you - you'll need to decide if this has any real-world impact on your application.
Option 2: Using a custom PropertyValidator.
This uses a custom custom validator which can differentiate the underlying type at runtime:
public WizardValidator : AbstractValidator<Wizard> {
public WizardValidator() {
RuleForEach(x => x.Steps).SetValidator(new PolymorphicValidator<Wizard, IWizardStep>()
.Add<WizardOne>(new WizardOneValidator())
.Add<WizardTwo>(new WizardTwoValidator())
);
}
}
Syntactically, this isn't quite as nice, but doesn't bypass the expression cache and doesn't iterate the collection multiple times. This is the code for the PolymorphicValidator:
public class PolymorphicValidator<T, TInterface> : ChildValidatorAdaptor<T, TInterface> {
readonly Dictionary<Type, IValidator> _derivedValidators = new Dictionary<Type, IValidator>();
// Need the base constructor call, even though we're just passing null.
public PolymorphicValidator() : base((IValidator<TInterface>)null, typeof(IValidator<TInterface>)) {
}
public PolymorphicValidator<T, TInterface> Add<TDerived>(IValidator<TDerived> derivedValidator) where TDerived : TInterface {
_derivedValidators[typeof(TDerived)] = derivedValidator;
return this;
}
public override IValidator<TInterface> GetValidator(PropertyValidatorContext context) {
// bail out if the current item is null
if (context.PropertyValue == null) return null;
if (_derivedValidators.TryGetValue(context.PropertyValue.GetType(), out var derivedValidator)) {
return new ValidatorWrapper(derivedValidator);
}
return null;
}
private class ValidatorWrapper : AbstractValidator<TInterface> {
private IValidator _innerValidator;
public ValidatorWrapper(IValidator innerValidator) {
_innerValidator = innerValidator;
}
public override ValidationResult Validate(ValidationContext<TInterface> context) {
return _innerValidator.Validate(context);
}
public override Task<ValidationResult> ValidateAsync(ValidationContext<TInterface> context, CancellationToken cancellation = new CancellationToken()) {
return _innerValidator.ValidateAsync(context, cancellation);
}
public override IValidatorDescriptor CreateDescriptor() {
return _innerValidator.CreateDescriptor();
}
}
}
This will probably be implemented in the library as a first class feature at some point in the future - you can track its development here if you're interested.

Changing aggregate behavior during its lifetime

Imagine that we have an Aggregate that has a life cycle, such that it can change its behavior during its lifetime. During the first part of its life, it can do some things and during the second part, it can do other things.
I´d like to hear opinions on how should we restrict what the aggregate can do on each phase.
To make it a little more tangible, lets take an financial trade as an aggreagate example.
A trader creates a trade informing the contract, and its price.
A risk manager validates a trade, giving a reason for such.
The BackOffice can submit the trade to the ledger, providing accounting information.
After the trade is submitted, the accounting information can never be changed.
The trade clearly has 3 distinct phases, which I´ll call Typed, Validated and Submitted
My first thought is to pollute the aggregate with InvalidOperationExceptions, which I really don´t like:
public class Trade
{
private enum State { Typed, Validated, Submited }
private State _state = State.Typed;
public Guid Id { get; }
public Contract Contract { get; }
public decimal Price { get; }
public Trade (Guid id, Contract contract, decimal price) { ... }
private string _validationReason = null;
private AccountingInformation _accInfo = null;
public void Validate(string reason) {
if (_state != State.Typed)
throw new InvalidOperationException (..)
...
_validationReason = reason;
_state = State.Validated;
}
public string GetValidationReason() {
if (_state == State.Typed)
throw new InvalidOperationException (..)
return _validationReason;
}
public void SubmitToLedger(AccountingInformation info) {
if ((_state != State.Validated))
throw new InvalidOperationException (..)
...
}
public AccountingInfo GetAccountingInfo() { .. }
}
I can do something like a Maybe pattern, to avoid the exceptions on the Get... methods. But that would not work for the behavior methods (Validate, SubmitToLedger, etc)
Oddly, if I were to be working on a functional language (such as F#), I would probably create a different type for each state.
type TypedTrade = { Id : Guid; Contract: Contract; Price : decimal }
type ValidatedTrade = { Id : Guid;
Contract: Contract;
Price : decimal;
ValidationReason : string}
type SubmittedTrade = { Id : Guid;
Contract: Contract;
Price : decimal;
ValidationReason : string;
AccInfo : AccountingInfo }
// TypedTrade -> string -> ValidatedTrade
let validateTrade typedTrade reason =
...
{ Id = typedTrade.Id; Contract = typedTrade.Contract;
Price = typedTrade.Price; Reason = reason }
// ValidatedTrade -> AccountingInfo -> SubmittedTrade
let submitTrade validatedTrade accInfo =
...
{ Id = validatedTrade.Id;
Contract = validatedTrade.Contract;
Price = validatedTrade.Price;
Reason = validatedTrad.Reason;
AccInfo = accInfo }
And the problem would gracefully go away. But to do that in OO, I would have to make my aggregate immutable and maybe create some kind o hierarchy (in which I would have to hide base methods !? ouch!).
I just wanted an opinion on what you guys do on these situations, and if there is a better way.
I like the idea of having different types for each state. Its a clean design in my opinion. From a logical view a newly created trade is definitly something different than a submitted trade.
public Interface ITrade
{
Guid Id { get; }
Contract Contract { get; }
decimal Price { get; }
}
public class Trade : ITrade
{
public Trade(Guid id, Contract contract, decimal price)
{
Id = id;
Contract = contract;
Price = price;
}
Guid Id { get; }
Contract Contract { get; }
decimal Price { get; }
public ValidatedTrade Validate(string reason)
{
return new ValidatedTrade(this, reason);
}
}
public class ValidatedTrade : ITrade
{
private ITrade trade;
private string validationReason;
public ValidatedTrade(Trade trade, string validationReason)
{
this.trade = trade;
this.validationReason = validationReason;
}
Guid Id { get { return trade.Id; } }
Contract Contract { get { return trade.Contract ; } }
decimal Price { get { return trade.Price ; } }
public string GetValidationReason()
{
return validationReason;
}
public SubmittedTrade SubmitToLedger(AccountingInfo accountingInfo)
{
return new SubmittedTrade(this, accountingInfo);
}
}
public class SubmittedTrade : ITrade
{
private ITrade trade;
private AccountingInfo accountingInfo;
public SubmittedTrade(ValidatedTrade trade, AccountingInfo accountingInfo)
{
this.trade = trade;
this.accountingInfo = accountingInfo;
}
Guid Id { get { return trade.Id; } }
Contract Contract { get { return trade.Contract ; } }
decimal Price { get { return trade.Price ; } }
public AccountingInfo GetAccountingInfo() { .. }
}
You could have one class per state instead of a single class. See this post by Greg Young : http://codebetter.com/gregyoung/2010/03/09/state-pattern-misuse/
The usual problem with the State pattern is the friction with persistence concerns and especially ORMs. It's up to you to decide if the better robustness and type safety is worth the trouble.

Refactoring Switching On Types Code Smell When Adding Method to Type Seems Inappropriate

Let's say I have the following method that, given a PaymentType, sends an appropriate payment request to each facility from which the payment needs to be withdrawn:
public void SendRequestToPaymentFacility(PaymentType payment) {
if(payment is CreditCard) {
SendRequestToCreditCardProcessingCenter();
} else if(payment is BankAccount) {
SendRequestToBank();
} else if(payment is PawnTicket) {
SendRequestToPawnShop();
}
}
Obviously this is a code smell, but when looking for an appropriate refactoring, the only examples I have seen involve cases where the code executed within the conditionals are clearly the responsibility of the class itself, e.g. with the standard example given:
public double GetArea(Shape shape) {
if(shape is Circle) {
Circle circle = shape As Circle;
return circle.PI * (circle.radius * circle.radius);
} else if(shape is Square) {
Square square = shape as Square;
return square.length * square.width;
}
}
GetArea() seems like a pretty reasonable responsibility for each Shape subclass, and can of course be refactored nicely:
public class Shape
{
/* ... */
public abstract double GetArea();
}
public class Circle
{
public override double GetArea()
{
return PI * (radius * radius);
}
}
However, SendRequestToPaymentFacility() does not seem like an appropriate responsibility for a PaymentType to have. (and would seem to violate the Single Responsibility Principle). And yet I need to send a request to an appropriate PaymentFacility based on the type of PaymentType - what is the best way to do this?
You could consider adding a property or method to your CandyBar class which indicates whether or not the CandyBar contains nuts. Now your GetProcessingPlant() method does not have to have knowledge of the different types of CandyBars.
public ProcessingPlant GetProcessingPlant(CandyBar candyBar) {
if(candyBar.ContainsNuts) {
return new NutProcessingPlant();
} else {
return new RegularProcessingPlant();
}
}
One option would be to add an IPaymentFacility interface parameter to the constructors for the individual PaymentType descendants. The base PaymentType could have an abstract PaymentFacility property; SendRequestToPaymentFacility on the base type would delegate:
public abstract class PaymentType
{
protected abstract IPaymentFacility PaymentFacility { get; }
public void SendRequestToPaymentFacility()
{
PaymentFacility.Process(this);
}
}
public interface IPaymentFacility
{
void Process(PaymentType paymentType);
}
public class BankAccount : PaymentType
{
public BankAccount(IPaymentFacility paymentFacility)
{
_paymentFacility = paymentFacility;
}
protected override IPaymentFacility PaymentFacility
{
get { return _paymentFacility; }
}
private readonly IPaymentFacility _paymentFacility;
}
Rather than wiring up the dependency injection manually, you could use a DI/IoC Container library. Configure it so that a BankAccount got a Bank, etc.
The downside is that the payment facilities would only have access to the public (or possibly internal) members of the base-class PaymentType.
Edit:
You can actually get at the descendant class members by using generics. Either make SendRequestToPaymentFacility abstract (getting rid of the abstract property), or get fancy:
public abstract class PaymentType<TPaymentType>
where TPaymentType : PaymentType<TPaymentType>
{
protected abstract IPaymentFacility<TPaymentType> PaymentFacility { get; }
public void SendRequestToPaymentFacility()
{
PaymentFacility.Process((TPaymentType) this);
}
}
public class BankAccount : PaymentType<BankAccount>
{
public BankAccount(IPaymentFacility<BankAccount> paymentFacility)
{
_paymentFacility = paymentFacility;
}
protected override IPaymentFacility<BankAccount> PaymentFacility
{
get { return _paymentFacility; }
}
private readonly IPaymentFacility<BankAccount> _paymentFacility;
}
public interface IPaymentFacility<TPaymentType>
where TPaymentType : PaymentType<TPaymentType>
{
void Process(TPaymentType paymentType);
}
public class Bank : IPaymentFacility<BankAccount>
{
public void Process(BankAccount paymentType)
{
}
}
The downside here is coupling the Bank to the BankAccount class.
Also, Eric Lippert discourages this, and he makes some excellent points.
One approach you can take here is to use the Command pattern. In this case, you would create and queue up the appropriate command (e.g. Credit Card, Bank Account, Pawn Ticket) rather than calling a particular method. Then you could have separate command processors for each command that would take the appropriate action.
If you don't want the conditional complexity here, you could raise a single type of command that included the payment type as a property, and then a command processor could be responsible for figuring out how to handle that request (with the appropriate payment processor).
Either of these could help your class follow Single Responsibility Principle by moving details of payment processing out of it.

Adding State in Decorator Pattern

I wonder how to add state to the chain of decorators that will be available to the consumer. Given this simplified model:
abstract class AbstractPizza
{
public abstract print(...);
}
class Pizza : AbstractPizza
{
public int Size { get; set; }
public print(...);
}
abstract class AbstractPizzaDecorator
{
public Pizza:AbstractPizza;
public abstract print();
}
class HotPizzaDecorator : AbstractPizzaDecorator
{
public int Hotness { get; set; }
public print(...);
}
class CheesyPizzaDecorator : AbstractPizzaDecorator
{
public string Cheese { get; set; }
public print(...);
}
void Main()
{
BigPizza = new Pizza();
BigPizza.Size = 36;
HotBigPizza = new HotPizzaDecorator();
HotBigPizza.Pizza = BigPizza;
HotBigPizza.Hotness = 3;
HotBigCheesyPizza = new CheesyPizzaDecorator();
HotBigCheesyPizza.Pizza = HotBigPizza;
HotBigCheesyPizza.Cheese = "Blue";
HotBigCheesyPizza.print();
HotBigCheesyPizza.size = 28; // ERRRRRR !
}
Now if they all implement the print method and propagate that though the chain, it's all good. But how does that work for the state? I can't access the size property on the HotBigCheesyPizza.
What's the part that I'm missing? Wrong pattern?
Thanks for helping!
Cheers
The decorator pattern is for adding additional behavior to the decorated class without the client needing to adjust. Thus it is not intended for adding a new interface (e.g. hotness, cheese) to the thing being decorated.
A somewhat bad example of what it might be used for is where you want to change how size is calculated: you could create a MetricSizePizzaDecorator that converts the size to/from English/metric units. The client would not know the pizza has been decorated - it just calls getSize() and does whatever it needs to do with the result (for example, to calculate the price).
I would probably not use the decorator in my example, but the point is: it does not alter the interface. In fact, nearly all design patterns come down to that - adding variability to a design without changing interfaces.
one way of adding state is by using a self referential data structure (a list). but this uses the visitor pattern and does more than you probably want. this code is rewritten from A little Java, a few patterns
// a self referential data structure with different types of nodes
abstract class Pie
{
abstract Object accept(PieVisitor ask);
}
class Bottom extends Pie
{
Object accept(PieVisitor ask) { return ask.forBottom(this); }
public String toString() { return "crust"; }
}
class Topping extends Pie
{
Object topping;
Pie rest;
Topping(Object topping,Pie rest) { this.topping=topping; this.rest=rest; }
Object accept(PieVisitor ask) { return ask.forTopping(this); }
public String toString() { return topping+" "+rest.toString(); }
}
//a class to manage the data structure
interface PieManager
{
int addTopping(Object t);
int removeTopping(Object t);
int substituteTopping(Object n,Object o);
int occursTopping(Object o);
}
class APieManager implements PieManager
{
Pie p=new Bottom();
// note: any object that implements a rational version of equal() will work
public int addTopping(Object t)
{
p=new Topping(t,p);
return occursTopping(t);
}
public int removeTopping(Object t)
{
p=(Pie)p.accept(new RemoveVisitor(t));
return occursTopping(t);
}
public int substituteTopping(Object n,Object o)
{
p=(Pie)p.accept(new SubstituteVisitor(n,o));
return occursTopping(n);
}
public int occursTopping(Object o)
{
return ((Integer)p.accept(new OccursVisitor(o))).intValue();
}
public String toString() { return p.toString(); }
}
//these are the visitors
interface PieVisitor
{
Object forBottom(Bottom that);
Object forTopping(Topping that);
}
class OccursVisitor implements PieVisitor
{
Object a;
OccursVisitor(Object a) { this.a=a; }
public Object forBottom(Bottom that) { return new Integer(0); }
public Object forTopping(Topping that)
{
if(that.topping.equals(a))
return new Integer(((Integer)(that.rest.accept(this))).intValue()+1);
else return that.rest.accept(this);
}
}
class SubstituteVisitor implements PieVisitor
{
Object n,o;
SubstituteVisitor(Object n,Object o) { this.n=n; this.o=o; }
public Object forBottom(Bottom that) { return that; }
public Object forTopping(Topping that)
{
if(o.equals(that.topping))
that.topping=n;
that.rest.accept(this);
return that;
}
}
class RemoveVisitor implements PieVisitor
{
Object o;
RemoveVisitor(Object o) { this.o=o; }
public Object forBottom(Bottom that) { return new Bottom(); }
public Object forTopping(Topping that)
{
if(o.equals(that.topping))
return that.rest.accept(this);
else return new Topping(that.topping,(Pie)that.rest.accept(this));
}
}
public class TestVisitor
{
public static void main(String[] args)
{
// make a PieManager
PieManager pieManager=new APieManager();
// add some toppings
pieManager.addTopping(new Float(1.2));
pieManager.addTopping(new String("cheese"));
pieManager.addTopping(new String("onions"));
pieManager.addTopping(new String("cheese"));
pieManager.addTopping(new String("onions"));
pieManager.addTopping(new String("peperoni"));
System.out.println("pieManager="+pieManager);
// substitute anchovies for onions
int n=pieManager.substituteTopping(new String("anchovies"),new String("onions"));
System.out.println(n+" pieManager="+pieManager);
// remove the 1.2's
n=pieManager.removeTopping(new Float(1.2));
System.out.println(n+" pieManager="+pieManager);
// how many anchovies do we have?
System.out.println(pieManager.occursTopping(new String("anchovies"))+" anchovies");
}
}
I believe your component Pizza and your abstract decorator PizzaDecorator are supposed to share the same interface, that way each instance of the decorator is capable of the same operations as the core component Pizza.

Fluent NHibermate and Polymorphism and a Newbie!

I'm a fluent nhibernate newbie and I'm struggling mapping a hierarchy of polymorhophic objects. I've produced the following Model that recreates the essence of what I'm doing in my real application.
I have a ProductList and several specialised type of products;
public class MyProductList
{
public virtual int Id { get; set; }
public virtual string Name {get;set;}
public virtual IList<Product> Products { get; set; }
public MyProductList()
{
Products = new List<Product>();
}
}
public class Product
{
public virtual int Id { get; set; }
public virtual string ProductDescription {get;set;}
}
public class SizedProduct : Product
{
public virtual decimal Size {get;set;}
}
public class BundleProduct : Product
{
public virtual Product BundleItem1 {get;set;}
public virtual Product BundleItem2 {get;set;}
}
Note that I have a specialised type of Product called BundleProduct that has two products attached.
I can add any of the specialised types of product to MyProductList and a bundle Product can be made up of any of the specialised types of product too.
Here is the fluent nhibernate mapping that I'm using;
public class MyListMap : ClassMap<MyList>
{
public MyListMap()
{
Id(ml => ml.Id);
Map(ml => ml.Name);
HasManyToMany(ml => ml.Products).Cascade.All();
}
}
public class ProductMap : ClassMap<Product>
{
public ProductMap()
{
Id(prod => prod.Id);
Map(prod => prod.ProductDescription);
}
}
public class SizedProductMap : SubclassMap<SizedProduct>
{
public SizedProductMap()
{
Map(sp => sp.Size);
}
}
public class BundleProductMap : SubclassMap<BundleProduct>
{
public BundleProductMap()
{
References(bp => bp.BundleItem1).Cascade.All();
References(bp => bp.BundleItem2).Cascade.All();
}
}
I haven't configured have any reverse mappings, so a product doesn't know which Lists it belongs to or which bundles it is part of.
Next I add some products to my list;
MyList ml = new MyList() { Name = "Example" };
ml.Products.Add(new Product() { ProductDescription = "PSU" });
ml.Products.Add(new SizedProduct() { ProductDescription = "Extension Cable", Size = 2.0M });
ml.Products.Add(new BundleProduct()
{
ProductDescription = "Fan & Cable",
BundleItem1 = new Product() { ProductDescription = "Fan Power Cable" },
BundleItem2 = new SizedProduct() { ProductDescription = "80mm Fan", Size = 80M }
});
When I persist my list to the database and reload it, the list itself contains the items I expect ie MyList[0] has a type of Product, MyList[1] has a type of SizedProduct, and MyList[2] has a type of BundleProduct - great!
If I navigate to the BundleProduct, I'm not able to see the types of Product attached to the BundleItem1 or BundleItem2 instead they are always proxies to the Product - in this example BundleItem2 should be a SizedProduct.
Is there anything I can do to resove this either in my model or the mapping?
Thanks in advance for your help.
As it stands, the BundleItem1 and BundleItem2 properties will always have a Product proxy because NH creates your proxies without touching the database, so it doesn't know if they are Products or some derived type. But when you call a method on your bundle items, NH should hit the DB and load the correct record, and you should get polymorphic behavior.
You could test this out. Add an override of ToString to your SizedProduct:
public override string ToString()
{
return "I'm a sized product!";
}
Then load your BundleProduct and do this:
Debug.WriteLine(bp.BundleItem1.ToString());
Debug.WriteLine(bp.BundleItem2.ToString());
You should find that the second call prints out "I'm a sized product!", and this will demonstrate that you have working polymorphism.
Assuming this all worked as I've described, its time to tackle the real question: what exactly do you want to do? Maybe you could provide some code that doesn't actually work as you would like it to.