开发者

desigining the domain model - need help

开发者 https://www.devze.com 2023-01-04 20:25 出处:网络
i know whats is happening and why its throwing an error (it does not find GetBrokenRules method because its List) but the reason i posted this question here is to ask for a better design, can anybody

i know whats is happening and why its throwing an error (it does not find GetBrokenRules method because its List) but the reason i posted this question here is to ask for a better design, can anybody guide me here please?

i am working on Facilities class (List..../Building/Floor)

error:

Error 3 'System.Collections.Generic.List' does not contain a definition for 'GetBrokenRules' and no extension method 'GetBrokenRules' accepting a first argument of type 'System.Collections.Generic.List' could be found (are you missing a using directive or an assembly reference?)

error on >>> else if (Campus.GetBrokenRules().Count > 0)

is there any better way to desing my GetBrokenRules() ?

ICampus, IBuilding, IFloor consists of the following

public interface ICampus
    {
        List<BrokenBusinessRule> GetBrokenRules(); 
        int Id { get; }
        string Name { get; }
    }

public interface IFacilities 
{
  开发者_高级运维  List<BrokenBusinessRule> GetBrokenRules();
    List<ICampus> Campus { get; }
    List<IBuilding> Building { get; }
    List<IFloor> Floor { get; }  
}


public class Facilities : IFacilities 
    {
        private List<ICampus> _campus;
        private List<IBuilding> _building;
        private List<IFloor> _floor;  

        public List<ICampus> Campus
        {
            get { return _campus; }
        } 

        public List<IBuilding> Building
        {
            get { return _building; }
        }

        public List<IFloor> Floor
        {
            get { return _floor; }
        } 

        public Facilities(List<ICampus> campus, List<IBuilding> building, List<IFloor> floor)
        {
            _campus = campus;
            _building = building;
            _floor = floor; 
        } 

        public  List<BrokenBusinessRule> GetBrokenRules()
        {
            List<BrokenBusinessRule> brokenRules = new List<BrokenBusinessRule>(); 

           if (Campus == null)
                brokenRules.Add(new BrokenBusinessRule("Facility Campus", "Must have at least one Campus"));
            else if (Campus.GetBrokenRules().Count > 0)
            {
                AddToBrokenRulesList(brokenRules, Campus.GetBrokenRules());
            }

            if (Building == null)
                brokenRules.Add(new BrokenBusinessRule("Facility Building", "Must have at least one Building"));
            else if (Building.GetBrokenRules().Count > 0)
            {
                AddToBrokenRulesList(brokenRules, Building.GetBrokenRules());
            }

            if (Floor == null)
                brokenRules.Add(new BrokenBusinessRule("Facility Floor", "Must have at least one Floor"));
            else if (Floor.GetBrokenRules().Count > 0)
            {
                AddToBrokenRulesList(brokenRules, Floor.GetBrokenRules());
            }       
    }
} 


public  List<BrokenBusinessRule> GetBrokenRules()
{
    var brokenRules = new List<BrokenBusinessRule>(); 

   // null is not possible because Campus is supplied in the constructor
   if (!Campus.Any())
        brokenRules.Add(new BrokenBusinessRule("Facility Campus", "Must have at least one Campus"));
   else
   {
       foreach(var campus in  Campus)
       {
           brokenRules.AddRange(campus.GetBrokenRules());
       }
   }

   if (!Building,Any())
        brokenRules.Add(new BrokenBusinessRule("Facility Building", "Must have at least one Building"));
    else
    {
        foreach(var building in Building)
        {
            brokenRules.AddRange(building.GetBrokenRules());
        }
    }

    if (!Floor.Any())
        brokenRules.Add(new BrokenBusinessRule("Facility Floor", "Must have at least one Floor"));
    else
    {
        foreach (var floor in Floor)
        {
            brokenRules.AddRange(floor.GetBrokenRules());
        }        
    }
    return brokenRules;     
}

As far as a redesign, I would first get rid of the ICampus, IBuilding, and IFloor interfaces and program against the classes. I would create an interface that declares the GetBrokenRules behavior and have the business classes implement that. Beyond that, it seems to me that a Campus has Buildings and a Building has Floors so I would design it that way instead of collecting these classes into a Facilities class.


Where are your definitions for ICampus, IBuilding and IFloor? Those seem to be integral to IFacilities. Also, you're calling GetBrokenRules() on a List of objects, rather than on the objects themselves.

I'm going to assume that ICampus, IBuilding and IFloor are defined properly and that, for now, the only problem is that you're calling the method on the list. You'll need to enumerate across the List and call that method on each item. Something like:

Campus.ForEach(c => AddToBrokenRulesList(brokenRules, c.GetBrokenRules()));

(You may need the nVentive Umbrella extensions for .ForEach, I don't remember. But there are other ways to enumerate over a List so that's not critical.)


GetBrokenRules() does not take any arguments, and it's not an extension method, so it has no idea what list it's supposed to process. More difficult than that, all the lists you want to process are defined as lists of different interface types, so there's no commonality there.

One way to handle this would be to define a new interface that defines the common processing for IBuilding, ICampus, and IFloor, and have each of those interfaces inherit from this new interface (call it IFacility). You could then define GetBrokenRules to take an argument of List, and pass it a List. GetBrokenRules would be able to call methods defined in IFacility, which might be sufficient to get passed your current problem.

However, you'll have to pass the list as an argument, rather than they way you're doing it now (Campus.GetBrokenRules()). You could use this syntax if you can get an extension method to work, but that can be tricky when defining extension methods on generic collections. I'd advise against that for now.


I would do the null checks in the constructor and take IEnumerables as argument instead of IList. You can call ToList() on the IEnumerables which has the side benefit of throwing an exception if it's null.

I'd create an IFacility interface with a GetBrokenRules method that returns and IEnumerable

public interface IFacility
{
    IEnumerable<BrokenRules> GetBrokenRules();
}

public static class Utils
{
    public static IEnumerable<BrokenRules> GetRules(this IEnumerable<IFacility> facilities)
    {
        return facilities.SelectMany(x => x.GetBrokenRules());
    }
}

Then have building, floor, campus, etc implement the IFacility interface.

0

精彩评论

暂无评论...
验证码 换一张
取 消