Dependency injection by type names
For my example I use Autofac (it's not necessary):
var r = builder.RegisterType<Helper>().As<IHelper>(); // usual using
What I'd like to do is to be able to register types somehow like:
string name1 = "Helper";
string name2 = "IHelper";
var r = builder.RegisterType<GetTypeFromName(name1)>().As<GetTypeFromName(name2)>();
Is it possible to do with reflection magic?
c# .net reflection dependency-injection autofac
add a comment |
For my example I use Autofac (it's not necessary):
var r = builder.RegisterType<Helper>().As<IHelper>(); // usual using
What I'd like to do is to be able to register types somehow like:
string name1 = "Helper";
string name2 = "IHelper";
var r = builder.RegisterType<GetTypeFromName(name1)>().As<GetTypeFromName(name2)>();
Is it possible to do with reflection magic?
c# .net reflection dependency-injection autofac
Possible duplicate of How do I use reflection to call a generic method?
– thehennyy
Nov 13 '18 at 19:26
add a comment |
For my example I use Autofac (it's not necessary):
var r = builder.RegisterType<Helper>().As<IHelper>(); // usual using
What I'd like to do is to be able to register types somehow like:
string name1 = "Helper";
string name2 = "IHelper";
var r = builder.RegisterType<GetTypeFromName(name1)>().As<GetTypeFromName(name2)>();
Is it possible to do with reflection magic?
c# .net reflection dependency-injection autofac
For my example I use Autofac (it's not necessary):
var r = builder.RegisterType<Helper>().As<IHelper>(); // usual using
What I'd like to do is to be able to register types somehow like:
string name1 = "Helper";
string name2 = "IHelper";
var r = builder.RegisterType<GetTypeFromName(name1)>().As<GetTypeFromName(name2)>();
Is it possible to do with reflection magic?
c# .net reflection dependency-injection autofac
c# .net reflection dependency-injection autofac
edited Nov 14 '18 at 13:03
Steven
127k17213330
127k17213330
asked Nov 13 '18 at 18:25
amplifieramplifier
490421
490421
Possible duplicate of How do I use reflection to call a generic method?
– thehennyy
Nov 13 '18 at 19:26
add a comment |
Possible duplicate of How do I use reflection to call a generic method?
– thehennyy
Nov 13 '18 at 19:26
Possible duplicate of How do I use reflection to call a generic method?
– thehennyy
Nov 13 '18 at 19:26
Possible duplicate of How do I use reflection to call a generic method?
– thehennyy
Nov 13 '18 at 19:26
add a comment |
3 Answers
3
active
oldest
votes
You would have to create a mechanism that would "figure out" which concrete types you want to register and how to expose them (the As
part in AutoFac). Here is a sample of how you can register using System.Type
so the missing part is obtaining the System.Type
s yourself.
// get your Type(s)
Type concreteType = typeof(Helper);
Type asType = typeof(IHelper);
// Autofac registration call
builder.RegisterType(concreteType).As(asType);
As you can see in the above code you should call the non-generic version of the RegisterType
and As
methods. (The generic versions really just call down to these anyways).
Hey, I even didn't think about non-generic version! Yes, I'm able to get both types, but unfortunately after resolving I get ComponentNotRegisteredException for 'asType' (IHelper). Any ideas?
– amplifier
Nov 13 '18 at 18:51
@amplifier - Does typeHelper
implement interfaceIHelper
?
– Igor
Nov 13 '18 at 18:53
Yes, it does. Checked it, otherwise my "static" resolver wouldn't work
– amplifier
Nov 13 '18 at 19:11
add a comment |
Generally to resolve a type name you would need to provide more information than just the class name. So I guess the answer is "not exactly".
The method for mapping a string to a type is Type.GetType
, which is documented here: https://docs.microsoft.com/en-us/dotnet/api/system.type.gettype?view=netframework-4.7.2
As you can see, in a vacuum we can't say that "Helper"
or "IHelper"
would be sufficient. You probably could get by with a namespace-qualified class name. (The reason why Helper
works in the "hard-coded" syntax, of course, is that the compiler can take advantage of using
statements in deciding what Helper
should mean. That option doesn't work when GetType
is trying to understand a string at runtime.)
If you can provide a custom resolver, maybe you can make it work exactly as you describe.
I can get type variable for Helper and IHelper this way: Type typeArgument = Assembly.LoadFrom(assemblyPath).GetTypes().First(t => t.Name == className);
– amplifier
Nov 13 '18 at 18:37
Sure, and if that suits your use case, it's fine. This means that you know what assembly the class comes from, which is a good place to start. But also beware of thatFirst
method, which may not do what you want if the assembly should happen to contain two classes (in different namespaces) with the same name.
– Mark Adelsberger
Nov 13 '18 at 18:41
add a comment |
If you're able to get te Type
object for the type you want to register, you can pass it to Autofac using a different overload of the RegisterType
method, like so:
var type = Assembly.LoadFrom(path).GetType(typeName);
builder.RegisterType(type);
Great! But after resolving IHelper via _container.Resolve<IHelper>(); I get ComponentNotRegisteredException for 'asType' (IHelper).
– amplifier
Nov 13 '18 at 18:53
If concrete type and interface types are different, you still have to use theAs()
method as you did before.
– John Wu
Nov 13 '18 at 19:04
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53287342%2fdependency-injection-by-type-names%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You would have to create a mechanism that would "figure out" which concrete types you want to register and how to expose them (the As
part in AutoFac). Here is a sample of how you can register using System.Type
so the missing part is obtaining the System.Type
s yourself.
// get your Type(s)
Type concreteType = typeof(Helper);
Type asType = typeof(IHelper);
// Autofac registration call
builder.RegisterType(concreteType).As(asType);
As you can see in the above code you should call the non-generic version of the RegisterType
and As
methods. (The generic versions really just call down to these anyways).
Hey, I even didn't think about non-generic version! Yes, I'm able to get both types, but unfortunately after resolving I get ComponentNotRegisteredException for 'asType' (IHelper). Any ideas?
– amplifier
Nov 13 '18 at 18:51
@amplifier - Does typeHelper
implement interfaceIHelper
?
– Igor
Nov 13 '18 at 18:53
Yes, it does. Checked it, otherwise my "static" resolver wouldn't work
– amplifier
Nov 13 '18 at 19:11
add a comment |
You would have to create a mechanism that would "figure out" which concrete types you want to register and how to expose them (the As
part in AutoFac). Here is a sample of how you can register using System.Type
so the missing part is obtaining the System.Type
s yourself.
// get your Type(s)
Type concreteType = typeof(Helper);
Type asType = typeof(IHelper);
// Autofac registration call
builder.RegisterType(concreteType).As(asType);
As you can see in the above code you should call the non-generic version of the RegisterType
and As
methods. (The generic versions really just call down to these anyways).
Hey, I even didn't think about non-generic version! Yes, I'm able to get both types, but unfortunately after resolving I get ComponentNotRegisteredException for 'asType' (IHelper). Any ideas?
– amplifier
Nov 13 '18 at 18:51
@amplifier - Does typeHelper
implement interfaceIHelper
?
– Igor
Nov 13 '18 at 18:53
Yes, it does. Checked it, otherwise my "static" resolver wouldn't work
– amplifier
Nov 13 '18 at 19:11
add a comment |
You would have to create a mechanism that would "figure out" which concrete types you want to register and how to expose them (the As
part in AutoFac). Here is a sample of how you can register using System.Type
so the missing part is obtaining the System.Type
s yourself.
// get your Type(s)
Type concreteType = typeof(Helper);
Type asType = typeof(IHelper);
// Autofac registration call
builder.RegisterType(concreteType).As(asType);
As you can see in the above code you should call the non-generic version of the RegisterType
and As
methods. (The generic versions really just call down to these anyways).
You would have to create a mechanism that would "figure out" which concrete types you want to register and how to expose them (the As
part in AutoFac). Here is a sample of how you can register using System.Type
so the missing part is obtaining the System.Type
s yourself.
// get your Type(s)
Type concreteType = typeof(Helper);
Type asType = typeof(IHelper);
// Autofac registration call
builder.RegisterType(concreteType).As(asType);
As you can see in the above code you should call the non-generic version of the RegisterType
and As
methods. (The generic versions really just call down to these anyways).
edited Nov 13 '18 at 18:43
answered Nov 13 '18 at 18:32
IgorIgor
39.4k349102
39.4k349102
Hey, I even didn't think about non-generic version! Yes, I'm able to get both types, but unfortunately after resolving I get ComponentNotRegisteredException for 'asType' (IHelper). Any ideas?
– amplifier
Nov 13 '18 at 18:51
@amplifier - Does typeHelper
implement interfaceIHelper
?
– Igor
Nov 13 '18 at 18:53
Yes, it does. Checked it, otherwise my "static" resolver wouldn't work
– amplifier
Nov 13 '18 at 19:11
add a comment |
Hey, I even didn't think about non-generic version! Yes, I'm able to get both types, but unfortunately after resolving I get ComponentNotRegisteredException for 'asType' (IHelper). Any ideas?
– amplifier
Nov 13 '18 at 18:51
@amplifier - Does typeHelper
implement interfaceIHelper
?
– Igor
Nov 13 '18 at 18:53
Yes, it does. Checked it, otherwise my "static" resolver wouldn't work
– amplifier
Nov 13 '18 at 19:11
Hey, I even didn't think about non-generic version! Yes, I'm able to get both types, but unfortunately after resolving I get ComponentNotRegisteredException for 'asType' (IHelper). Any ideas?
– amplifier
Nov 13 '18 at 18:51
Hey, I even didn't think about non-generic version! Yes, I'm able to get both types, but unfortunately after resolving I get ComponentNotRegisteredException for 'asType' (IHelper). Any ideas?
– amplifier
Nov 13 '18 at 18:51
@amplifier - Does type
Helper
implement interface IHelper
?– Igor
Nov 13 '18 at 18:53
@amplifier - Does type
Helper
implement interface IHelper
?– Igor
Nov 13 '18 at 18:53
Yes, it does. Checked it, otherwise my "static" resolver wouldn't work
– amplifier
Nov 13 '18 at 19:11
Yes, it does. Checked it, otherwise my "static" resolver wouldn't work
– amplifier
Nov 13 '18 at 19:11
add a comment |
Generally to resolve a type name you would need to provide more information than just the class name. So I guess the answer is "not exactly".
The method for mapping a string to a type is Type.GetType
, which is documented here: https://docs.microsoft.com/en-us/dotnet/api/system.type.gettype?view=netframework-4.7.2
As you can see, in a vacuum we can't say that "Helper"
or "IHelper"
would be sufficient. You probably could get by with a namespace-qualified class name. (The reason why Helper
works in the "hard-coded" syntax, of course, is that the compiler can take advantage of using
statements in deciding what Helper
should mean. That option doesn't work when GetType
is trying to understand a string at runtime.)
If you can provide a custom resolver, maybe you can make it work exactly as you describe.
I can get type variable for Helper and IHelper this way: Type typeArgument = Assembly.LoadFrom(assemblyPath).GetTypes().First(t => t.Name == className);
– amplifier
Nov 13 '18 at 18:37
Sure, and if that suits your use case, it's fine. This means that you know what assembly the class comes from, which is a good place to start. But also beware of thatFirst
method, which may not do what you want if the assembly should happen to contain two classes (in different namespaces) with the same name.
– Mark Adelsberger
Nov 13 '18 at 18:41
add a comment |
Generally to resolve a type name you would need to provide more information than just the class name. So I guess the answer is "not exactly".
The method for mapping a string to a type is Type.GetType
, which is documented here: https://docs.microsoft.com/en-us/dotnet/api/system.type.gettype?view=netframework-4.7.2
As you can see, in a vacuum we can't say that "Helper"
or "IHelper"
would be sufficient. You probably could get by with a namespace-qualified class name. (The reason why Helper
works in the "hard-coded" syntax, of course, is that the compiler can take advantage of using
statements in deciding what Helper
should mean. That option doesn't work when GetType
is trying to understand a string at runtime.)
If you can provide a custom resolver, maybe you can make it work exactly as you describe.
I can get type variable for Helper and IHelper this way: Type typeArgument = Assembly.LoadFrom(assemblyPath).GetTypes().First(t => t.Name == className);
– amplifier
Nov 13 '18 at 18:37
Sure, and if that suits your use case, it's fine. This means that you know what assembly the class comes from, which is a good place to start. But also beware of thatFirst
method, which may not do what you want if the assembly should happen to contain two classes (in different namespaces) with the same name.
– Mark Adelsberger
Nov 13 '18 at 18:41
add a comment |
Generally to resolve a type name you would need to provide more information than just the class name. So I guess the answer is "not exactly".
The method for mapping a string to a type is Type.GetType
, which is documented here: https://docs.microsoft.com/en-us/dotnet/api/system.type.gettype?view=netframework-4.7.2
As you can see, in a vacuum we can't say that "Helper"
or "IHelper"
would be sufficient. You probably could get by with a namespace-qualified class name. (The reason why Helper
works in the "hard-coded" syntax, of course, is that the compiler can take advantage of using
statements in deciding what Helper
should mean. That option doesn't work when GetType
is trying to understand a string at runtime.)
If you can provide a custom resolver, maybe you can make it work exactly as you describe.
Generally to resolve a type name you would need to provide more information than just the class name. So I guess the answer is "not exactly".
The method for mapping a string to a type is Type.GetType
, which is documented here: https://docs.microsoft.com/en-us/dotnet/api/system.type.gettype?view=netframework-4.7.2
As you can see, in a vacuum we can't say that "Helper"
or "IHelper"
would be sufficient. You probably could get by with a namespace-qualified class name. (The reason why Helper
works in the "hard-coded" syntax, of course, is that the compiler can take advantage of using
statements in deciding what Helper
should mean. That option doesn't work when GetType
is trying to understand a string at runtime.)
If you can provide a custom resolver, maybe you can make it work exactly as you describe.
edited Nov 13 '18 at 18:38
answered Nov 13 '18 at 18:33
Mark AdelsbergerMark Adelsberger
20.2k11221
20.2k11221
I can get type variable for Helper and IHelper this way: Type typeArgument = Assembly.LoadFrom(assemblyPath).GetTypes().First(t => t.Name == className);
– amplifier
Nov 13 '18 at 18:37
Sure, and if that suits your use case, it's fine. This means that you know what assembly the class comes from, which is a good place to start. But also beware of thatFirst
method, which may not do what you want if the assembly should happen to contain two classes (in different namespaces) with the same name.
– Mark Adelsberger
Nov 13 '18 at 18:41
add a comment |
I can get type variable for Helper and IHelper this way: Type typeArgument = Assembly.LoadFrom(assemblyPath).GetTypes().First(t => t.Name == className);
– amplifier
Nov 13 '18 at 18:37
Sure, and if that suits your use case, it's fine. This means that you know what assembly the class comes from, which is a good place to start. But also beware of thatFirst
method, which may not do what you want if the assembly should happen to contain two classes (in different namespaces) with the same name.
– Mark Adelsberger
Nov 13 '18 at 18:41
I can get type variable for Helper and IHelper this way: Type typeArgument = Assembly.LoadFrom(assemblyPath).GetTypes().First(t => t.Name == className);
– amplifier
Nov 13 '18 at 18:37
I can get type variable for Helper and IHelper this way: Type typeArgument = Assembly.LoadFrom(assemblyPath).GetTypes().First(t => t.Name == className);
– amplifier
Nov 13 '18 at 18:37
Sure, and if that suits your use case, it's fine. This means that you know what assembly the class comes from, which is a good place to start. But also beware of that
First
method, which may not do what you want if the assembly should happen to contain two classes (in different namespaces) with the same name.– Mark Adelsberger
Nov 13 '18 at 18:41
Sure, and if that suits your use case, it's fine. This means that you know what assembly the class comes from, which is a good place to start. But also beware of that
First
method, which may not do what you want if the assembly should happen to contain two classes (in different namespaces) with the same name.– Mark Adelsberger
Nov 13 '18 at 18:41
add a comment |
If you're able to get te Type
object for the type you want to register, you can pass it to Autofac using a different overload of the RegisterType
method, like so:
var type = Assembly.LoadFrom(path).GetType(typeName);
builder.RegisterType(type);
Great! But after resolving IHelper via _container.Resolve<IHelper>(); I get ComponentNotRegisteredException for 'asType' (IHelper).
– amplifier
Nov 13 '18 at 18:53
If concrete type and interface types are different, you still have to use theAs()
method as you did before.
– John Wu
Nov 13 '18 at 19:04
add a comment |
If you're able to get te Type
object for the type you want to register, you can pass it to Autofac using a different overload of the RegisterType
method, like so:
var type = Assembly.LoadFrom(path).GetType(typeName);
builder.RegisterType(type);
Great! But after resolving IHelper via _container.Resolve<IHelper>(); I get ComponentNotRegisteredException for 'asType' (IHelper).
– amplifier
Nov 13 '18 at 18:53
If concrete type and interface types are different, you still have to use theAs()
method as you did before.
– John Wu
Nov 13 '18 at 19:04
add a comment |
If you're able to get te Type
object for the type you want to register, you can pass it to Autofac using a different overload of the RegisterType
method, like so:
var type = Assembly.LoadFrom(path).GetType(typeName);
builder.RegisterType(type);
If you're able to get te Type
object for the type you want to register, you can pass it to Autofac using a different overload of the RegisterType
method, like so:
var type = Assembly.LoadFrom(path).GetType(typeName);
builder.RegisterType(type);
answered Nov 13 '18 at 18:46
John WuJohn Wu
29.9k42752
29.9k42752
Great! But after resolving IHelper via _container.Resolve<IHelper>(); I get ComponentNotRegisteredException for 'asType' (IHelper).
– amplifier
Nov 13 '18 at 18:53
If concrete type and interface types are different, you still have to use theAs()
method as you did before.
– John Wu
Nov 13 '18 at 19:04
add a comment |
Great! But after resolving IHelper via _container.Resolve<IHelper>(); I get ComponentNotRegisteredException for 'asType' (IHelper).
– amplifier
Nov 13 '18 at 18:53
If concrete type and interface types are different, you still have to use theAs()
method as you did before.
– John Wu
Nov 13 '18 at 19:04
Great! But after resolving IHelper via _container.Resolve<IHelper>(); I get ComponentNotRegisteredException for 'asType' (IHelper).
– amplifier
Nov 13 '18 at 18:53
Great! But after resolving IHelper via _container.Resolve<IHelper>(); I get ComponentNotRegisteredException for 'asType' (IHelper).
– amplifier
Nov 13 '18 at 18:53
If concrete type and interface types are different, you still have to use the
As()
method as you did before.– John Wu
Nov 13 '18 at 19:04
If concrete type and interface types are different, you still have to use the
As()
method as you did before.– John Wu
Nov 13 '18 at 19:04
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53287342%2fdependency-injection-by-type-names%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Possible duplicate of How do I use reflection to call a generic method?
– thehennyy
Nov 13 '18 at 19:26