40

私のブートストラッパーで:

namespace Conduit.Mam.ClientServices.Common.Initizliaer
{
    public static class Initializer
    {
        private static bool isInitialize;
        private static readonly object LockObj = new object();
        private static IUnityContainer defaultContainer = new UnityContainer();

        static Initializer()
        {
            Initialize();
        }

        public static void Initialize()
        {
            if (isInitialize)
                return;

            lock (LockObj)
            {
                IUnityContainer container = defaultContainer;

                //registering Unity for MVC
                DependencyResolver.SetResolver(new UnityDependencyResolver(container));

                //registering Unity for web API
                //  GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);

                #region managers
                container.RegisterType<ISettingsManager, SettingsManager>();

                container.RegisterType<IMamDataManager, MamDataManager>();

                container.RegisterType<IAppsDataManager, AppsDataManager>();
                #endregion

                if (!isInitialize)
                {
                    isInitialize = true;
                }
            }
        }
    }
}

私のコントローラーのコードで:

ISettingsManager sm = mUnityContainer.Resolve<ISettingsManager>();

mUnityContainerにカーソルを合わせると、ISettingsManagerマップされていることがわかりますSettingsManager

しかし、その後エラーが発生します:

例外: InvalidOperationException - 現在の型はインターフェイスであり、構築できません。タイプマッピングがありませんか?

私も試してみました

ISettingsManager sm = (ISettingsManager)mUnityContainer.Resolve<>(typeof(ISettingsManager));

しかし、役に立たない

4

7 に答える 7

46

上記のエラーに直面した可能性のある他の人(私のような人)のために。簡単な言葉での解決策。

コードでインターフェイスとクラス (そのインターフェイスを実装する) の登録を忘れている可能性があります。

たとえば、エラーが
現在の型 xyznamespace.Imyinterfacenameインターフェイスであり、構築できません。型マッピングがありませんか?"

次に、 RegisterメソッドのUnityConfigクラスにImyinterfacenameを実装するクラスを登録する必要があります。以下のようなコードを使用して

 container.RegisterType<Imyinterfacename, myinterfaceimplclassname>();
于 2015-07-08T02:04:59.977 に答える
20

依存性注入を誤って使用しています。適切な方法は、コントローラーに必要な依存関係を取得させ、具体的なインスタンスを注入する依存関係注入フレームワークに任せることです。

public class HomeController: Controller
{
    private readonly ISettingsManager settingsManager;
    public HomeController(ISettingsManager settingsManager)
    {
        this.settingsManager = settingsManager;
    }

    public ActionResult Index()
    {
        // you could use the this.settingsManager here
    }
}

この例でわかるように、コントローラーはコンテナーについて何も知りません。そして、それがそうあるべきです。

すべての DI 配線は Bootstraper で行う必要があります。container.Resolve<>コード内で呼び出しを使用しないでください。

エラーに関する限り、おそらくmUnityContainerコントローラー内で使用しているインスタンスは、ブートストラップで構築されたインスタンスと同じではありません。しかし、コントローラーでコンテナー コードを使用するべきではないため、これはもう問題にはなりません。

于 2013-01-27T16:31:21.683 に答える
9

私の場合、問題のインターフェイスの既存のインスタンスを登録しているにもかかわらず、このエラーが発生していました。

結局のところ、 Unity.WebForms Nuget パッケージを介して WebForms で Unity を使用していたことが原因であり、インスタンスを提供していた依存関係に Hierarchical Lifetime マネージャーを指定していましたが、後続のタイプには Transient ライフタイム マネージャーを指定していました。以前のタイプに依存していました-通常は問題ではありません-しかし、Unity.WebFormsでは、ライフタイムマネージャーの動作が少し異なります...注入されたタイプには階層型ライフタイムマネージャーが必要なようですが、Webリクエストごとに新しいコンテナーが作成されます(私が推測する Web フォームのアーキテクチャのため)この投稿で見事に説明されています。

とにかく、登録時にタイプ/インスタンスのライフタイムマネージャーを指定しないことで解決しました。

すなわち

container.RegisterInstance<IMapper>(MappingConfig.GetMapper(), new HierarchicalLifetimeManager());    
container.RegisterType<IUserContext, UserContext>(new TransientLifetimeManager());

になる

container.RegisterInstance<IMapper>(MappingConfig.GetMapper());
container.RegisterType<IUserContext, UserContext>();

ここで IMapper を正常に解決できるようにします。

public class UserContext : BaseContext, IUserContext
{
    public UserContext(IMapper _mapper) : base(_mapper)
    {

    }
    ...
}
于 2016-05-15T20:28:48.010 に答える
0

以下のコードはあなたに役立ちます

public static IUnityContainer Initialise(IUnityContainer container = null)
{
    if (container == null)
    {
        container = new UnityContainer();
    }
    container.RegisterType<ISettingsManager, SettingsManager>();
    container.Resolve<SettingsManager>();
    container.RegisterType<SettingsManagerController>(new InjectionProperty("_SettingManagerProvider", new ResolvedParameter<ISettingManager>()));
    return container;
}
于 2018-08-06T12:57:43.863 に答える
0

私の場合、Unitofwork と Ioc コンテナーで 2 つの異なるコンテキストを使用したため、サービス層が 2 番目のリポジトリを DI に挿入しようとしている間、この問題が主張していることがわかります。その理由は、既存のモジュールには、構築されていない新しいリポジトリからの呼び出しを取得することになっている他のモジュール インスタンスとコンテナーが含まれているためです。

于 2016-04-26T07:13:59.237 に答える