{"id":25735491,"url":"https://github.com/kalebpederson/nunit.dependencyinjection","last_synced_at":"2025-08-21T12:34:27.298Z","repository":{"id":33571642,"uuid":"156462895","full_name":"kalebpederson/nunit.dependencyinjection","owner":"kalebpederson","description":"Add support to NUnit for constructor injection using an inversion control container, such as Unity or Autofac.","archived":false,"fork":false,"pushed_at":"2022-02-17T20:01:24.000Z","size":158,"stargazers_count":9,"open_issues_count":6,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-15T02:20:11.798Z","etag":null,"topics":["dependency-injection","extension","nunit","unity-container"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kalebpederson.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-06T23:35:05.000Z","updated_at":"2025-03-11T15:02:08.000Z","dependencies_parsed_at":"2022-08-28T21:12:17.349Z","dependency_job_id":null,"html_url":"https://github.com/kalebpederson/nunit.dependencyinjection","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kalebpederson%2Fnunit.dependencyinjection","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kalebpederson%2Fnunit.dependencyinjection/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kalebpederson%2Fnunit.dependencyinjection/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kalebpederson%2Fnunit.dependencyinjection/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kalebpederson","download_url":"https://codeload.github.com/kalebpederson/nunit.dependencyinjection/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252968102,"owners_count":21833251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency-injection","extension","nunit","unity-container"],"created_at":"2025-02-26T05:23:03.531Z","updated_at":"2025-05-07T23:02:44.997Z","avatar_url":"https://github.com/kalebpederson.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Introduction \n\nOutside of pure unit tests it sometimes becomes desirable to do dependency\ninjection in automated tests. By their nature these aren't the typical unit\ntests as they have dependencies. These could be, for example, acceptance\ntests against a standalone application. The dependencies to be injected, in\nthis case, might be things to provide information about the environment to\nhit, such as hostnames and database connection strings, or may be client\nSDKs to the system under test. This framework is intended to support these\nscenarios.\n\n# Warning\nGood **unit tests** shouldn't need to inject dependencies into the test fixture.\nIf you need dependency injection into a test fixture in unit tests then\nconsider whether the design of the system could be changed in such a way that\nthe system under test can be easily unit tested without that need.\n\nFrom here on out it is assumed that the purpose for dependency injection\nwithin tests has been validated and is appropriate.\n\n# API Stability\nIn accordance with semantic versioning, all versions prior to 1.0 are assumed\npre-releases and are **NOT** subject to API/ABI compatibility.\n\n# Usage\n\nThe below is **subject to change at our whims until version 1.0**, though note\nthat we don't expect it to change. For a working example see the different test \nprojects in the Validation folder.\n\nTwo different mechanisms are currently provided by which dependencies are\ndiscovered, though custom processes can be added as well:\n\n1. Explicit registration of dependencies via the `IIocRegistrar`\n1. Convention based assembly scanning and registration of types\n\nThese approaches are described below.\n\n## Discovery/Scanning of all `IIocRegistrar`s\n\nWhen many different assemblies are present it can become difficult to\nautomatically register all interfaces with their corresponding concrete types.\nOr, perhaps we prefer that everything be manually registered to make the\nprocess and choice very explicit. The example below demonstrates that process:\n\n```csharp\n// First import the following NuGet packages: \n// * NUnit.Extension.DependencyInjection\n// * NUnit.Extension.DependencyInjection.Abstractions\n// * NUnit.Extension.DependencyInjection.Unity\n\nusing NUnit.Extension.DependencyInjection;\nusing NUnit.Extension.DependencyInjection.Abstractions;\nusing NUnit.Extension.DependencyInjection.Unity;\n\n// tell the extension that we will be using the Microsoft Unity Injection\n// factory\n[assembly: NUnitTypeInjectionFactory(typeof(UnityInjectionFactory))]\n\n// If we want to manually register the different types we need to create\n// one or more implementations of IIocRegistrar that register with the\n// container and then use the IocRegistrarTypeDiscoverer.\n[assembly: NUnitTypeDiscoverer(typeof(IocRegistrarTypeDiscoverer))]\n\n// The registrar above will scan for implementations of IIocRegistrar,\n// which the RegistrarBase class implements, and then execute each\n// discovered registrations:\npublic class MyRegistrar : RegistrarBase\u003cIUnityContainer\u003e\n{\n  protected override void RegisterInternal(IUnityContainer container)\n  {\n    container.RegisterType\u003cIDependency1, Dependency1\u003e();\n    container.RegisterType\u003cIDependency2, Dependency2\u003e();\n  }\n}\n\n// Loaded assemblies are scanned for interfaces and corresponding concrete\n// definitions. For example:\npublic interface IDependency1 {}\npublic interface IDependency2 {}\n\npublic class Dependency1 : IDependency1 { }\n\n// Instead of using the [TestFixture] attribute when declaring a test class\n// you'll need to decorate the class with a DependencyInjectingTestFixture\n// attribute:\n[NUnit.Extension.DependencyInjection.DependencyInjectingTestFixture]\npublic class MyTests\n{\n  private readonly IDependency1 _dependency1;\n  private readonly IDependency2 _dependency2;\n\n  // once everything is properly configured, dependencies can be injected\n  // directly into the constructor\n  public MyTests(IDependency1 dependency1, IDependency2 dependency2)\n  {\n    _dependency1 = dependency1;\n    _dependency2 = dependency2;\n  }\n\n  [Test]\n  public void Test_something_using_IDependency1()\n  {\n    Assert.That(_dependency1, Is.Not.Null);\n    Assert.That(_dependency1, Is.InstanceOf\u003cDependency1\u003e());\n  }\n}\n```\n\n## Convention Based Type Discovery\n\nSometimes it's convenient if the inversion of control container picks up all\nof the interfaces and their mapping registrations automatically. For example,\ngiven an interface `IDateTimeProvider` and a corresponding implementation\n`DateTimeProvider`, we might want to register the interface `IDateTimeProvider`\nas corresponding to the concrete implementation of `DateTimeProvider`.\nThis example demonstrates that process:\n\n```csharp\n// First import the following NuGet packages: \n// * NUnit.Extension.DependencyInjection\n// * NUnit.Extension.DependencyInjection.Abstractions\n// * NUnit.Extension.DependencyInjection.Unity\n\nusing NUnit.Extension.DependencyInjection;\nusing NUnit.Extension.DependencyInjection.Abstractions;\nusing NUnit.Extension.DependencyInjection.Unity;\n\n// tell the extension that we will be using the Microsoft Unity Injection\n// factory\n[assembly: NUnitTypeInjectionFactory(typeof(UnityInjectionFactory))]\n\n// If we wanted to automatically register all interfaces with their concrete\n// implementations for which the NUnitAutoScanAssembly attribute is present on\n// the assembly is present we could do the following:\n[assembly: NUnitTypeDiscoverer(typeof(ConventionMappingTypeDiscoverer))]\n\n// When using the ConventionMappingTypeDiscoverer it can be problematic and\n// dangerous to scan lots of framework assemblies and types and pre-register \n// them, so assemblies to be scanned **MUST** be decorated with the \n// NUnitAutoScanAssembly attribute.\n[assembly: NUnit.Extension.DependencyInjection.NUnitAutoScanAssembly]\n\n// Loaded assemblies are scanned for interfaces and corresponding concrete\n// definitions. For example:\npublic interface IDependency1 {}\npublic interface IDependency2 {}\n\npublic class Dependency1 : IDependency1 { }\n\n// Instead of using the [TestFixture] attribute when declaring a test class\n// you'll need to decorate the class with a DependencyInjectingTestFixture\n// attribute:\n[NUnit.Extension.DependencyInjection.DependencyInjectingTestFixture]\npublic class MyTests\n{\n  private readonly IDependency1 _dependency1;\n  private readonly IDependency2 _dependency2;\n\n  // once everything is properly configured, dependencies can be injected\n  // directly into the constructor\n  public MyTests(IDependency1 dependency1, IDependency2 dependency2)\n  {\n    _dependency1 = dependency1;\n    _dependency2 = dependency2;\n  }\n\n  [Test]\n  public void Test_something_using_IDependency1()\n  {\n    Assert.That(_dependency1, Is.Not.Null);\n    Assert.That(_dependency1, Is.InstanceOf\u003cDependency1\u003e());\n  }\n}\n```\n\n## Manual `IIocRegistrar` Selection\n\nWhen conflicting `IIocRegistrars` are present it's not possible to use assembly\nscanning. In this case, it's helpful to create a single `IIocRegistrar` that is\nmanually defined and which will perform all necessary registrations.\n\n\n```csharp\n// First import the following NuGet packages: \n// * NUnit.Extension.DependencyInjection\n// * NUnit.Extension.DependencyInjection.Abstractions\n// * NUnit.Extension.DependencyInjection.Unity\n\nusing NUnit.Extension.DependencyInjection;\nusing NUnit.Extension.DependencyInjection.Abstractions;\nusing NUnit.Extension.DependencyInjection.Unity;\n\n// tell the extension that we will be using the Microsoft Unity Injection\n// factory\n[assembly: NUnitTypeInjectionFactory(typeof(UnityInjectionFactory))]\n\n// If we wanted to automatically register all interfaces with their concrete\n// implementations for which the NUnitAutoScanAssembly attribute is present on\n// the assembly is present we could do the following:\n[assembly: NUnitTypeDiscoverer(\n  typeof(ManualRegistrarTypeDiscoverer\u003cBundlingRegistrar\u003e))]\n\npublic class BundlingRegistrar : RegistrarBase\u003cIUnityContainer\u003e\n{\n  /// \u003cinheritdoc /\u003e\n  protected override void RegisterInternal(IUnityContainer container)\n  {\n    container.RegisterType\u003cIDependency1, Dependency1\u003e();\n    container.RegisterType\u003cIDependency2, Dependency2\u003e();\n  }\n}\n\n// Loaded assemblies are scanned for interfaces and corresponding concrete\n// definitions. For example:\npublic interface IDependency1 {}\npublic interface IDependency2 {}\n\npublic class Dependency1 : IDependency1 { }\n\n// Instead of using the [TestFixture] attribute when declaring a test class\n// you'll need to decorate the class with a DependencyInjectingTestFixture\n// attribute:\n[NUnit.Extension.DependencyInjection.DependencyInjectingTestFixture]\npublic class MyTests\n{\n  private readonly IDependency1 _dependency1;\n  private readonly IDependency2 _dependency2;\n\n  // once everything is properly configured, dependencies can be injected\n  // directly into the constructor\n  public MyTests(IDependency1 dependency1, IDependency2 dependency2)\n  {\n    _dependency1 = dependency1;\n    _dependency2 = dependency2;\n  }\n\n  [Test]\n  public void Test_something_using_IDependency1()\n  {\n    Assert.That(_dependency1, Is.Not.Null);\n    Assert.That(_dependency1, Is.InstanceOf\u003cDependency1\u003e());\n  }\n}\n```\n# Changelog\n\n* **0.7.1** - Fix a bug where the message was set as a parameter name in some\n  argument exceptions that were thrown. Explicitly set the version range of allowed\n  NuGet packages so there's no confusion when performing package updates. Update\n  PowerShell scripts to run on Windows and Linux.\n* **0.7.0** - Introduces a NUnit.Extension.DependencyInjection.Abstractions assembly\n  to ease the process of creating convention based type discoverers while ensuring\n  that they don't need to depend directly on NUnit or any particular concrete types.\n* **0.6.0** - Make it possible to create `ITypeDiscover`s that require parameters\n  for configuration.\n  \n# Contributing\n\nPlease submit a PR. If the change is major it may be worth filing an issue first\neven if only it only serves as a mechanism for discussion to ensure that the\nwork your doing aligns with the goals of this project.\n\nFor more information on the project structure and validation process please see\nthe [Development_Readme.md](Development_Readme.md) document.\n\n# Troubleshooting\n\nAlthough we have put a lot of effort into ensuring that the error messages are\ndescriptive and self-explanatory, unfortunately many of the test runners hide\nerror messages that occur while setting up the test. Suggested steps:\n\n1. Verify that all the steps required to setup dependency injection for the\n   given type discoverer have been performed.\n\n1. If possible, run the test using `dotnet test` or the native NUnit test\n   runner as they provide better error information, such as the full exception\n   and stack trace.\n\n# TODO\n\n1. **Support for other containers** - Autofac and other containers that are more \npopular should be supported. I may just target the new .NET Core dependency \ninjection abstractions in hopes that it will be a sufficient bridge between all\nothers.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkalebpederson%2Fnunit.dependencyinjection","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkalebpederson%2Fnunit.dependencyinjection","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkalebpederson%2Fnunit.dependencyinjection/lists"}