私のブートストラップで:
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));
でもダメ
依存関係注入を誤って使用しています。適切な方法は、コントローラーに必要な依存関係を取得させ、依存関係注入フレームワークに具体的なインスタンスを注入させることです。
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
}
}
この例でわかるように、コントローラーはコンテナーについて何も知りません。そして、それはそうあるべきです。
BootstraperですべてのDI配線を行う必要があります。コードでcontainer.Resolve<>
呼び出しを使用しないでください。
エラーに関する限り、おそらくコントローラー内で使用しているmUnityContainer
は、Bootstraperで作成されたものと同じインスタンスではありません。しかし、コントローラーでコンテナーコードを使用するべきではないので、これはもう問題になりません。
上記のエラーに直面したかもしれない他の人(私のような)のために。簡単な用語でのソリューション。
インターフェースとクラス(そのインターフェースを実装する)登録をコードに登録するのを忘れているかもしれません。
例:エラーが
"現在のタイプxyznamespace。Imyinterfacenameはインターフェースであり、構築できません。タイプマッピングがありませんか?"
次に、nityConfigクラスのImyinterfacenameを実装するクラスを登録する必要がありますRegisterメソッド。以下のようなコードを使用して
container.RegisterType<Imyinterfacename, myinterfaceimplclassname>();
私の場合、問題のインターフェイスの既存のインスタンスを登録しているにもかかわらず、このエラーが発生していました。
判明したのは、 nity.WebForms Nugetパッケージを使用してWebFormsでUnityを使用しており、インスタンスを提供している依存関係に階層的ライフタイムマネージャーを指定していたためです。以前のタイプに依存する後続のタイプのライフタイムマネージャー-通常は問題ではありませんが、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)
{
}
...
}
以下のコードはあなたに役立ちます
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;
}
この問題が発生したのは、Microsoft.Owin.Host.SystemWeb NuGetパッケージをプロジェクトに追加していなかったことが原因です。スタートアップクラスのコードは正しいものの、実行されていませんでした。
したがって、この問題を解決しようとしている場合は、Unityの登録を行うコードにブレークポイントを配置します。ヒットしなければ、依存性注入は機能しません。
私の場合、UnitofworkとIocコンテナで2つの異なるコンテキストを使用しているため、サービスレイヤーがDIに2番目のリポジトリを挿入しようとしている間、この問題が持続することがわかります。その理由は、existモジュールに、構築されていない新しいリポジトリからの呼び出しを取得することになっている他のモジュールインスタンスとコンテナが含まれているためです。
コントローラーを登録していない可能性があります。以下のコードを試してください:
手順1.モデルフォルダーにdefaultcontrollerfactoryを実装して、独自のコントローラーファクトリクラスControllerFactory:DefaultControllerFactoryを作成します。
public class ControllerFactory :DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
try
{
if (controllerType == null)
throw new ArgumentNullException("controllerType");
if (!typeof(IController).IsAssignableFrom(controllerType))
throw new ArgumentException(string.Format(
"Type requested is not a controller: {0}",
controllerType.Name),
"controllerType");
return MvcUnityContainer.Container.Resolve(controllerType) as IController;
}
catch
{
return null;
}
}
public static class MvcUnityContainer
{
public static UnityContainer Container { get; set; }
}
}
ステップ2:BootStrapに登録する:inBuildUnityContainerメソッド
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
//RegisterTypes(container);
container = new UnityContainer();
container.RegisterType<IProductRepository, ProductRepository>();
MvcUnityContainer.Container = container;
return container;
}
ステップ3:Global Asaxで。
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
Bootstrapper.Initialise();
ControllerBuilder.Current.SetControllerFactory(typeof(ControllerFactory));
}
これで完了です