Laden...

Fehlermeldung bei Dependency Injection (Microsoft.Extension.DependenyInjection)

Letzter Beitrag vor einem Monat 5 Posts 246 Views
Fehlermeldung bei Dependency Injection (Microsoft.Extension.DependenyInjection)

Hallo Zusammen,

ich beisse mir gerade die Zähne aus und verstehe nicht, warum ich hier eine FehlerMessage erhalte. Hier meine Ausgangssituation: Um das Single-Responsibility-Prinzip einzuhalten möchte ich gerne in meinen Projekt die Klassen entkoppeln. Dabei habe ich das Nudget: Microsoft.Extension.DependenyInjection installiert.

In meine Solution gibt es die Klasse Charakter sowie die Schnittstelle ICharakter:

using Nature.Models;
namespace Nature.Contracts
{
    public interface ICharacter
    {
        Character GetPlayerCharakter();
        void CreateNewCharacter(string charname, int gender);
    }
}
  using Nature.Contracts;
  public class Character : ICharacter
  {
      // Klassenvariable
      private readonly ICharacter? _player;

        // Eigenschaften
        public string CharName {get; set;}
        public int Gender {get; set;} 

      // Konstruktor
      public Character(IClassicPlayer player)
      {
          _player = player;         
      }

      // Objectverweis
     public void CreateNewCharacter(string charname, int gender)
     {
         this.CharName = charname;
         this.gender = gender;
     }

Weiterhin habe ich ein DI Container mit IOC eingerichtet in eine separate Klasse:

using Microsoft.Extensions.DependencyInjection;
using Nature.Contracts;
using Nature.Models;

namespace Nature.Services
{
    internal class ObjectProvider
    {
        public static void CreateObjects()
        {
            IServiceCollection collection = new ServiceCollection();
            collection.AddTransient<ICharacter, Character>();
                     
           IServiceProvider provider = collection.BuildServiceProvider();
           Character character = provider.GetService<Character>()!;
           character.CreateNewCharacter("Sotti", 0);
        }
    }
}

Nun bekomme ich folgenden Fehler und verstehen diesen nicht. Was mache ich falsch. In der Solution gibt es keine Fehler. Während der Laufzeit wird eigentlich ein Objekt Character eröffnet, aber ich komme dann folgenden Fehler:

System.IO.FileNotFoundException: "Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Das System kann die angegebene Datei nicht finden."

Kann mir einer helfen?

VIele Grüße

Poolgate

"Microsoft.Extensions.DependencyInjection.Abstractions" ist ein NuGet-Package, das von "Microsoft.Extensions.DependencyInjection" genutzt wird und eigentlich automatisch mit installiert werden sollte.

Das Problem ist, dass er das nicht findet, der Grund dafür ist aber nicht in dem von dir gezeigten Code, sondern irgendwo anders.
Hast Du ungewöhnliche Projekt-Einstellungen (csproj-Datei)? Dann wären diese Einstellungen wichtig.
Oder benutzt Du eine andere Software (z.B. Unity), sodass in Verbindung damit etwas schief gegangen ist? Dann müsstest Du dich damit auseinandersetzen, ggf. behandeln die Abhängigkeiten anders.
Oder tritt der Fehler nicht beim Debuggen auf, sondern erst, wenn Du das Programm irgendwo anders hin kopierst und von dort aus startest? Dann hast Du zu wenig kopiert, generell sollte man das Programm nicht einfach nur kopieren, sondern die Publish-Funktion nutzen, das kannst Du dann gezielt einstellen und bekommst alles ausgegeben, was notwendig ist - je nach Einstellungen.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

Typischer Fall, wenn so ein Fehler auftaucht ist, dass Du das NuGet falsch in Dein Projekt gesetzt hast.
Hast Du direkt eine Assembly referenziert, oder wirklich das NuGet Paket "installiert", in Deiner csproj?

Es wird sich wegen Microsoft.Extension.DependenyInjection.Abstraction beschwert, aber Du nennst Microsoft.Extension.DependenyInjection.
Der Verweis auf Microsoft.Extension.DependenyInjection ist hier korrekt, das Abstraction ist eine sub-dependency (und notwendig).

Daher weitere Möglichkeiten:

  • Du hast ein Paket referenziert, das nicht zu Deiner .NET Version passt
  • Dein .NET Restore hat nicht funktioniert

Zum Thema:

Ich weiß nicht, was Dein Ziel ist, aber DI ist eigentlich nicht dafür da, so Instanzen von (in Deinem Fall) Charaktere zu erstellen. Zumindest wäre das sehr sehr unüblich. Fühlt sich für mich nach zu viel des Guten an - etwas over engineered.
Das DI dürfte auch nicht funktionieren, weil dem DI Provider die Info fehlt, wie ein Charakter erstellt wird. Du hast einen Konstruktor, der Parameter erwartet - die kennt aber das DI nicht.

Ein üblicherer Fall wäre, dass Du eine Factory erstellst, die einen Charakter erzeugt, und die Factory ist über DI zugreifbar. Die Idee von DI ist schließlich zB Implementierungen zu tauschen und Abhängigkeiten zu lösen.

IServiceCollection services = new ServiceCollection();
services.AddTransient<ICharacterFactory, CharacterFactory>();

IServiceProvider provider = services.BuildServiceProvider();
ICharacterFactory factory = provider.GetRequiredService<ICharacterFactory >();

ICharacter newChar = factory.Create("Sotti", 0); // liefert zB das ICharacter als Character-Class

Damit ist Dein Code von der Implementierung der Factory getrennt; Du kannst jederzeit damit eine andere Factory registrieren, ohne Deinen Code ändern zu müssen.

services.AddTransient<ICharacterFactory, CharacterFactoryDieNochVielBesserIst>();
ICharacter newChar = factory.Create("Sotti", 0); // liefert zB das ICharacter dann als zB BetterCharacter-Class

Das ganze nennt sich Factory Pattern: https://refactoring.guru/design-patterns/factory-method/csharp/example

hier ist mein csproj:

<Project Sdk="Microsoft.NET.Sdk">
 <PropertyGroup>
   <TargetFramework>net6.0</TargetFramework>
   <ImplicitUsings>enable</ImplicitUsings>
   <Nullable>enable</Nullable>
   <BaseOutputPath>C:\Users\sasch\Desktop\Projekt\resources\server</BaseOutputPath>
   <GeneratePackageOnBuild>False</GeneratePackageOnBuild>
   <EnforceCodeStyleInBuild>False</EnforceCodeStyleInBuild>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
 </PropertyGroup>
 <ItemGroup>
   <PackageReference Include="AltV.Net" Version="16.2.2" />
   <PackageReference Include="AltV.Net.Async" Version="16.2.2" />
   <PackageReference Include="AltV.Net.Async.CodeGen" Version="16.2.2" />
   <PackageReference Include="AltV.Net.CApi" Version="16.2.2" />
   <PackageReference Include="AltV.Net.Client" Version="16.2.2" />
   <PackageReference Include="AltV.Net.ColShape" Version="16.2.2" />
   <PackageReference Include="AltV.Net.EntitySync" Version="1.18.0" />
   <PackageReference Include="AltV.Net.EntitySync.ServerEvent" Version="16.2.2" />
   <PackageReference Include="AltV.Net.Interactions" Version="16.2.2" />
   <PackageReference Include="AltV.Net.Resources.Chat.Api" Version="16.2.2" />
   <PackageReference Include="AltV.Net.Shared" Version="16.2.2" />
   <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
   <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
 </ItemGroup>
</Project>

I benutze net6.0 und have als Projekt eine Klassenbibliothek gewählt. Altv ist ein API um einen Gameserver zu errichten. Ich habe hier nichts fehlerhaftes endeckt

Hier ist mein Github:

https://github.com/Poolgates/Nature

Leider sind nicht die Standard Server Files drauf, aber mein Code 😉