Alternatives to type casting in your domain

In my Domain I have an entity Activity which has a list of ITasks. Each implementation of this task has it’s own properties beside the implementation of ITask itself. Now each operation of the Activity entity (e.g. Execute()) only needs to loop over this list and call an ITask method (e.g. ExecuteTask()).

Where I’m having trouble is when a specific tasks’ properties needs to be updated, as in configuring the task (not as part of the execute method). How do I get an instance of that task? The options I see are:

  • Get the Activity by Id and cast the task I need. This’ll either sprinkle my code with:
    • Tasks.OfType<SpecificTask>().Single(t => t.Id == taskId)
    • or Tasks.Single(t => t.Id == taskId) as SpecificTask
  • Make each task unique in the whole system (make each task an entity), and create a new repository for each ITask implementation

I don’t like either option, the first because I don’t like casting: I’m using NHibernate and I’m sure this’ll come back and bite me when I start using Lazy Loading (NHibernate currently uses proxies to implement this). I don’t like the second option because there are/will be dozens of different kind of tasks. Which would mean I’d have to create as many repositories.

Am I missing a third option here? Or are any of my objections to the two options not justified? How have you solved this problem in the past?

5

It is true that casting is bad when it introduces coupling. But that doesn’t mean it’s always bad. There’s not a lot wrong with

ITask task = Tasks.Single(t => t.Id == taskId);
IArduousTask arduous = task as IArduousTask;

if (arduous != null)
{
    arduous.HaveLunchBreak();
}

task.DoTask();

This way, we’re not tied to an implementation of ITask or IArduousTask. And any task can implement IArduousTask (with a different implementation of HaveLunchBreak(), if you choose) and HaveLunchBreak will automatically get called. But tasks that don’t implement IArduousTask will not break.

However, in your case, you should probably also reconsider whether your Task objects should be mutable. It might be better to do this:

ITask updated = task.GetUpdated(someData);
activity.UpdateTask(updated);

Where GetUpdated is a new method on ITask and activity.UpdateTask matches on updated.ID and replaces the entire object in the array. This leaves the implementation of GetUpdated to the task type itself.

someData can either be all the data that could possibly be required to perform an update of any type of task, or it could be a dictionary (or dynamic object) containing data from a task-specific UI, passed into a specific task.

1

Activity should not know about the special property.

This knowledge belongs to a virtual method in the task class like this:

public class MyTask
{
    public virtual void ExecuteTask()
    {
        // ....
    }
}

public class MyTaskWithSpecialProperty : MyTask
{
    public int MySpecialProperty {get;set}
    public override void ExecuteTask()
    {
        CalculateSpecialProperty();
        base.ExecuteTask();
    }
    private void CalculateSpecialProperty()
    {
            MySpecialProperty++;
    }
}

Activity does not need to know about MySpecialProperty when executing

public class Activity 
{
    public void ExecuteTasks()
    {
        foreach(var task in this.Tasks)
            task.ExecuteTask();
    }
}

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật