diff --git a/LightweightIocContainer/Exceptions/MultipleRegistrationException.cs b/LightweightIocContainer/Exceptions/MultipleRegistrationException.cs index b37f3e8..d64a728 100644 --- a/LightweightIocContainer/Exceptions/MultipleRegistrationException.cs +++ b/LightweightIocContainer/Exceptions/MultipleRegistrationException.cs @@ -8,16 +8,16 @@ using LightweightIocContainer.Interfaces; namespace LightweightIocContainer.Exceptions { /// - /// The is already registered in this + /// The is already registered differently in this /// internal class MultipleRegistrationException : IocContainerException { /// - /// The is already registered in this + /// The is already registered differently in this /// /// The that is already registered in this public MultipleRegistrationException(Type type) - : base($"Type {type.Name} is already registered in this IocContainer.") => + : base($"Type {type.Name} is already registered differently in this IocContainer.") => Type = type; /// diff --git a/LightweightIocContainer/IocContainer.cs b/LightweightIocContainer/IocContainer.cs index 2c7e393..35590a7 100644 --- a/LightweightIocContainer/IocContainer.cs +++ b/LightweightIocContainer/IocContainer.cs @@ -88,8 +88,8 @@ namespace LightweightIocContainer /// The is already registered in this private void Register(IRegistration registration) { - //if type is already registered //fixMe: Remove and check if already registered registration is the same - if (Registrations.Any(r => r.InterfaceType == registration.InterfaceType)) + IRegistration? sameTypeRegistration = Registrations.FirstOrDefault(r => r.InterfaceType == registration.InterfaceType); + if (sameTypeRegistration != null && !registration.Equals(sameTypeRegistration)) //if type is already registered differently throw new MultipleRegistrationException(registration.InterfaceType); if (registration is IInternalValidationProvider validationProvider) diff --git a/LightweightIocContainer/LightweightIocContainer.xml b/LightweightIocContainer/LightweightIocContainer.xml index 7872d01..f81ed54 100644 --- a/LightweightIocContainer/LightweightIocContainer.xml +++ b/LightweightIocContainer/LightweightIocContainer.xml @@ -211,7 +211,7 @@ - A base for the + A base for the @@ -234,12 +234,12 @@ - The is already registered in this + The is already registered differently in this - The is already registered in this + The is already registered differently in this The that is already registered in this diff --git a/LightweightIocContainer/Registrations/MultipleRegistration.cs b/LightweightIocContainer/Registrations/MultipleRegistration.cs index 9c3a3ae..0a24fb6 100644 --- a/LightweightIocContainer/Registrations/MultipleRegistration.cs +++ b/LightweightIocContainer/Registrations/MultipleRegistration.cs @@ -30,7 +30,7 @@ namespace LightweightIocContainer.Registrations /// /// A of s that are registered within this /// - public List Registrations { get; protected set; } + public List Registrations { get; protected init; } } /// diff --git a/LightweightIocContainer/Registrations/MultitonRegistration.cs b/LightweightIocContainer/Registrations/MultitonRegistration.cs index 0d9a265..083cc13 100644 --- a/LightweightIocContainer/Registrations/MultitonRegistration.cs +++ b/LightweightIocContainer/Registrations/MultitonRegistration.cs @@ -49,5 +49,11 @@ namespace LightweightIocContainer.Registrations base.ValidateFactory(); } + + public override bool Equals(object? obj) => obj is MultitonRegistration multitonRegistration && + base.Equals(obj) && + Scope == multitonRegistration.Scope; + + public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), Scope); } } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/OpenGenericRegistration.cs b/LightweightIocContainer/Registrations/OpenGenericRegistration.cs index ed7d4de..0ecd184 100644 --- a/LightweightIocContainer/Registrations/OpenGenericRegistration.cs +++ b/LightweightIocContainer/Registrations/OpenGenericRegistration.cs @@ -43,5 +43,11 @@ namespace LightweightIocContainer.Registrations base.Validate(); } + + public override bool Equals(object? obj) => obj is OpenGenericRegistration openGenericRegistration && + base.Equals(obj) && + ImplementationType == openGenericRegistration.ImplementationType; + + public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), ImplementationType); } } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/RegistrationBase.cs b/LightweightIocContainer/Registrations/RegistrationBase.cs index ca5b45a..c95d968 100644 --- a/LightweightIocContainer/Registrations/RegistrationBase.cs +++ b/LightweightIocContainer/Registrations/RegistrationBase.cs @@ -213,5 +213,35 @@ namespace LightweightIocContainer.Registrations } } } + + public override bool Equals(object? obj) + { + if (obj is not RegistrationBase registrationBase) + return false; + + if (Parameters == null && registrationBase.Parameters != null) + return false; + + if (Parameters != null && registrationBase.Parameters == null) + return false; + + if (Parameters?.Length != registrationBase.Parameters?.Length) + return false; + + if (Factory == null && registrationBase.Factory != null) + return false; + + if (Factory != null && registrationBase.Factory == null) + return false; + + if (Factory?.CreateMethods.Count != registrationBase.Factory?.CreateMethods.Count) + return false; + + return InterfaceType == registrationBase.InterfaceType && + Lifestyle == registrationBase.Lifestyle && + DisposeStrategy == registrationBase.DisposeStrategy; + } + + public override int GetHashCode() => HashCode.Combine(InterfaceType, (int) Lifestyle); } } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/SingleTypeRegistration.cs b/LightweightIocContainer/Registrations/SingleTypeRegistration.cs index 2f31602..bcf89ab 100644 --- a/LightweightIocContainer/Registrations/SingleTypeRegistration.cs +++ b/LightweightIocContainer/Registrations/SingleTypeRegistration.cs @@ -41,5 +41,21 @@ namespace LightweightIocContainer.Registrations FactoryMethod = factoryMethod; return this; } + + public override bool Equals(object? obj) + { + if (obj is not SingleTypeRegistration singleTypeRegistration) + return false; + + if (FactoryMethod == null && singleTypeRegistration.FactoryMethod != null) + return false; + + if (FactoryMethod != null && singleTypeRegistration.FactoryMethod == null) + return false; + + return base.Equals(obj); + } + + public override int GetHashCode() => base.GetHashCode(); } } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs b/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs index 984feac..56277b5 100644 --- a/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs +++ b/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs @@ -12,7 +12,7 @@ namespace LightweightIocContainer.Registrations /// The registration that is used to register an abstract typed factory /// /// The of the abstract typed factory - public class TypedFactoryRegistration : ITypedFactoryRegistration + internal class TypedFactoryRegistration : ITypedFactoryRegistration { /// /// The registration that is used to register an abstract typed factory @@ -29,5 +29,11 @@ namespace LightweightIocContainer.Registrations /// The class that contains the implemented abstract factory of this /// public ITypedFactory Factory { get; } + + public override bool Equals(object? obj) => obj is TypedFactoryRegistration factoryRegistration && + Factory.CreateMethods.Count == factoryRegistration.Factory.CreateMethods.Count && + InterfaceType == factoryRegistration.InterfaceType; + + public override int GetHashCode() => HashCode.Combine(InterfaceType); } } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/TypedRegistration.cs b/LightweightIocContainer/Registrations/TypedRegistration.cs index 344059d..99b8e6f 100644 --- a/LightweightIocContainer/Registrations/TypedRegistration.cs +++ b/LightweightIocContainer/Registrations/TypedRegistration.cs @@ -58,5 +58,24 @@ namespace LightweightIocContainer.Registrations /// Validate the for the and /// protected override void ValidateDisposeStrategy() => ValidateDisposeStrategy(ImplementationType); + + public override bool Equals(object? obj) + { + if (obj is not TypedRegistration typedRegistration) + return false; + + if (!base.Equals(obj)) + return false; + + if (OnCreateAction == null && typedRegistration.OnCreateAction != null) + return false; + + if (OnCreateAction != null && typedRegistration.OnCreateAction == null) + return false; + + return ImplementationType == typedRegistration.ImplementationType; + } + + public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), ImplementationType); } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/IocContainerTest.cs b/Test.LightweightIocContainer/IocContainerTest.cs index 6c92ac2..b323f3d 100644 --- a/Test.LightweightIocContainer/IocContainerTest.cs +++ b/Test.LightweightIocContainer/IocContainerTest.cs @@ -146,13 +146,27 @@ namespace Test.LightweightIocContainer public void TestInvalidMultitonRegistration() => Assert.Throws(() => _iocContainer.Register(r => r.Add(Lifestyle.Multiton))); [Test] - public void TestRegisterMultiple() + public void TestRegisterMultipleDifferent() { _iocContainer.Register(r => r.Add()); MultipleRegistrationException exception = Assert.Throws(() => _iocContainer.Register(r => r.Add())); Assert.AreEqual(typeof(ITest), exception?.Type); } + + [Test] + public void TestRegisterMultipleSame() + { + _iocContainer.Register(r => r.Add()); + Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add())); + } + [Test] + public void TestRegisterMultipleSameWithParameters() + { + _iocContainer.Register(r => r.Add().WithParameters("test", 1, new Foo())); + Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add().WithParameters("test", 1, new Foo()))); + } + [Test] public void TestResolveNotRegistered() {