Skip to content

DependencyOverride incorrect matches #200

Open
@ENikS

Description

@ENikS

DependencyOverride

The DependencyOverride provides an override for any resolved dependency that matches the contract.

Usage

Override is passed to the Resolve method alone with Type and Name of the requested contract:

Container.Resolve(someType, someName, new DependencyOverride(target, type, name, someValue)

Variants

public DependencyOverride(Type contractType,  ...)
public DependencyOverride(string contractName, ...)
public DependencyOverride(Type contractType, string? contractName, ...)

Override by Type

The constructor DependencyOverride(Type contractType, ...) creates an override that matches any dependency with specified `Type' regardless of dependency name. So many of these imports will match the override:

TestType(TDependency value)
TestTypeNamed([OptionalDependency("Name")] TDependency value)
TestType([Dependency] TDependency value)

Override by Name

The constructor string contractName creates an override that matches any dependency with specified contractName, regardless of the dependency's Type. So many of these imports will match the override:

TestTypeNamed([OptionalDependency("Name")] Type1 value)
TestType([Dependency("Name")] Type2 value)

Override by Contract

Finally, the constructor DependencyOverride(Type contractType, string? contractName, ...) creates an override that matches only dependencies with exact Type and contracts Name.

Problems

The current implementation has several issues:

  • DependencyOverride creates false positives on targeted overrides
  • Overrides are not matched to dependencies correctly
  • Type override only works for "null" name

False positives

During the equality check, the target is ignored. This example illustrates the issue:

[TestMethod]
public void SomeDescriptiveName()
{
  var a = new DependencyOverride(typeof(object), typeof(object), string.Empty, OverrideValue);
  var b = new DependencyOverride(typeof(string), typeof(object), string.Empty, OverrideValue);

  Assert.IsFalse(a.Equals(b));
}

So, during resolution, this override will be applied to either target.

Not matching to dependency

This example illustrates the issue:

[TestMethod]
public void CtorParameterNative()
{
    // Arrange
    Container.RegisterType<Service>(new InjectionConstructor("data"));

    // Act
    var value = Container.Resolve<Service>(new DependencyOverride(typeof(string), "override"));

    // Verify
    Assert.AreEqual("override", value.Data);
}

A type Service is registered with a container and requested to inject a constructor with the string "data".
During resolution, a DependencyOverride for type 'string' is passed into the Resolve. This override should be applied to every dependency with the type string, but it fails.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions