cslaforum icon indicating copy to clipboard operation
cslaforum copied to clipboard

Interface on BusinessListBase

Open CrossSlide opened this issue 5 years ago • 18 comments

I have an Interface "IPermits" with a member "Permits" for a business object with children, (BO, BLO, BO).

public class PermitsRO : BusinessListBase<PermitsRO, PermitRO>, IPermits

PROBLEM: BO.Permits.Where(r => !r.Deleted) says IPermits does not contain the "Where" definition. How do I implement "Where" for the interface?

Thanks

Version and Platform CSLA version: 4.6.3 OS: Windows Platform: WPF

CrossSlide avatar Mar 10 '20 10:03 CrossSlide

Is the Permits member return a list? If IPermits represents a list, you could require that interface uses a base implementation from IEnumerable or IEnumerable<T>, where T is your child object (or another interface representing the child object).

hurcane avatar Mar 10 '20 12:03 hurcane

Thanks @hurcane. As you can tell I'm kind of new to Interfaces. I'm just trying to reproduce the BusinessListBase functionality in my "IPermits". Not sure what that requires or how. Any help is appreciated. Thanks

`public class PermitWorkOrder : BusinessBase<PermitWorkOrder>, IPermitWorkOrder {...} public interface IPermitWorkOrder { int Id { get; } IPermits Permits { get; } }

public class Permits : BusinessListBase<Permits, Permit>, IPermits {...} public interface IPermits : IEnumerable? {}

public class Permit : BusinessBase<Permit>, IPermit {...} public interface IPermit { int Id { get; } int Version { get; } }`

CrossSlide avatar Mar 10 '20 12:03 CrossSlide

I think you are close. The IPermits interface should be IEnumerable<IPermit>

However, you are also asking for the Deleted property, which is not on your interface? Perhaps you need IPermit to also inherit from an interface that has the Deleted property? Is that one of the Csla methods you want to expose?

hurcane avatar Mar 10 '20 12:03 hurcane

I can't even do wo.PermitsRO[0].SomeProperty. wo.PermitsRO[0] say cannot apply indexing...

CrossSlide avatar Mar 10 '20 13:03 CrossSlide

IPermits can inherit from IBusinessListBase to gain the behaviour of BusinessListBase. You can do something like

public interface IPermit : IBusinessBase { }

public interface IPermits : IBusinessListBase<IPermit> { }

danielmartind avatar Mar 10 '20 13:03 danielmartind

Thank you @danielmartind for the help! When I apply IPermits to my Permits BLO it asks for the interface members. I auto implemented their signature but I don't think my methods are correct because now my normal Permits class (not using the interface) says it can't see the .Where statement. Any ideas? I may be doing this totally wrong. Sorry.

Thanks for the help.

INTERFACE MEMBERS ` public bool IsReadOnly => this.IsReadOnly;

    IPermitRO IList<IPermitRO>.this[int index] { get => this[index]; set => this.Add(value); }

    public int IndexOf(IPermitRO item)
    {
        return IndexOf(item);
    }

    public void Insert(int index, IPermitRO item)
    {
        Insert(index, item);
    }

    public void Add(IPermitRO item)
    {
        Add(item);
    }

    public bool Contains(IPermitRO item)
    {
        return Contains(item);
    }

    public void CopyTo(IPermitRO[] array, int arrayIndex)
    {
        CopyTo(array, arrayIndex);
    }

    public bool Remove(IPermitRO item)
    {
        return Remove(item);
    }

    IEnumerator<IPermitRO> IEnumerable<IPermitRO>.GetEnumerator()
    {
        return GetEnumerator();
    }

`

CrossSlide avatar Mar 10 '20 16:03 CrossSlide

You can still inherit from BusinessListBase then you don't need to implement all the methods yourself.


public interface IPermit : IBusinessBase { }

    public interface IPermits : IBusinessListBase<IPermit> { }

    [Serializable]
    public class Permit : BusinessBase<Permit>, IPermit { }

    [Serializable]
    public class Permits : BusinessListBase<Permits, IPermit>, IPermits { }

danielmartind avatar Mar 10 '20 17:03 danielmartind

Thanks again @danielmartind . Unfortunately if I use IPermit instead of Permit in the BLO it causes legacy code problems. So I have to implement the methods. Am I thinking about this right?

` public class Permits : BusinessListBase<Permits, IPermit>, IPermits { } vs. public class Permits : BusinessListBase<Permits, Permit>, IPermits { }

`

CrossSlide avatar Mar 10 '20 17:03 CrossSlide

public interface IPermits : IBusinessListBase<Permit> { } will also work

danielmartind avatar Mar 10 '20 17:03 danielmartind

Wow, that seems to have solved it! I'll have to test... Thank you @danielmartind for your help and patience. I owe you a couple of beers. ;-)

CrossSlide avatar Mar 10 '20 18:03 CrossSlide

may be @danielmartind doesn't drink alcohol : ) , he is from Lancashire! Lancashire county had a great cricket team in the late 90s : ) :)

Chicagoan2016 avatar Mar 10 '20 21:03 Chicagoan2016

After testing, the last suggestion did not work as hoped. IBusinessListBase<Permit> needs to stay <IPermit>.

Has anyone here implemented interface members on a BusinessListBase?

The Problem: As soon as I add an interface to my BusinessList I loose the LINQ ".Where, etc." extensions on my BOs but it's works when accessing the BOs through the interface. (e.g. Dog.Meals.Where()… not working, ((IPet)Dog).PetFoods.Where()… working)

NEW TEST OBJECTS: public class Dog : BusinessBase<Dog>, IPet { Meals... } public class Cat : BusinessBase<Cat>, IPet { Foods... } public interface IPet : IBusinessBase { IPetFoods... }

public class Meals : BusinessListBase<Meals, Meal>, IPetFoods public class Foods : BusinessListBase<Foods, Food>, IPetFoods public interface IPetFoods : IBusinessListBase<IPetFood>

public class Meal : BusinessBase<Meal>, IPetFood public class Food : BusinessBase<Food>, IPetFood public interface IPetFood : IBusinessBase

I assume my implementation of the interface methods are incorrect and causing the problem.

INTERFACE METHODS:

public class Meals : BusinessListBase<Meals, Meal>, IPetFoods
    {
		IPetFood IList<IPetFood>.this[int index] { get => this[index]; set => Add(value); }

		IEnumerator<IPetFood> IEnumerable<IPetFood>.GetEnumerator()
		{
			return GetEnumerator();
		}

		public bool IsReadOnly => IsReadOnly;

		public void Add(IPetFood item)
		{
			throw new NotImplementedException();
		}

		public bool Contains(IPetFood item)
		{
			return Contains(item);
		}

		public void CopyTo(IPetFood[] array, int arrayIndex)
		{
			throw new NotImplementedException();
		}

		public int IndexOf(IPetFood item)
		{
			return IndexOf(item);
		}

		public void Insert(int index, IPetFood item)
		{
			throw new NotImplementedException();
		}

		public bool Remove(IPetFood item)
		{
			return Remove(item);
		}
	}

Thanks for the help!!

CrossSlide avatar Mar 12 '20 16:03 CrossSlide

@rockfordlhotka I apologize for calling on you directly but I’ve been stumped on this problem for several days. If you get a minute can you help? Thanks

CrossSlide avatar Mar 16 '20 10:03 CrossSlide

I skimmed this thread, and it is not clear to me what you are trying to accomplish.

You want to cast the collection as an IPermits type? Why?

rockfordlhotka avatar Mar 16 '20 15:03 rockfordlhotka

I have some methods that I want to pass different BOs. public void DoSomething(IPet pet) <- so I can pass cat and dog and have them treated the same.

CrossSlide avatar Mar 16 '20 16:03 CrossSlide

OK, and in that DoSomething method you need the interface to reflect that it is a collection as well as whatever custom methods you are adding?

rockfordlhotka avatar Mar 16 '20 16:03 rockfordlhotka

Yes, I do a Pet.PetFoods.Where() in my method and it works but now my original Dog.Meals will not do the .Were()

(e.g. Dog.Meals.Where()… not working, ((IPet)Dog).PetFoods.Where()… working)... above

CrossSlide avatar Mar 16 '20 16:03 CrossSlide

This might be simpler in gitter - better for interactive conversation

https://gitter.im/MarimerLLC/cslaforum

rockfordlhotka avatar Mar 16 '20 16:03 rockfordlhotka