I have different Processor objects that implement IProcessor and I need to instantiate/resolve a processor within a method based on a string value that’s passed in. Something like:
var myClass = "Project.Processors.FastProcessor";
MyMethod(myClass);
Public void MyMethod(string myClass)
{
var processor = container.Resolve< myClass >();
}
Is this achievable with castle windsor?
var processor = container.Resolve(Type.GetType(myClass));
Related
I am using Autofac With ASP.NET Webforms. I would like to understand the difference between InstancePerLifetimeScope and InstancePerRequest when i register dependencies in the App_Start method of the global.asx.
It look like that for both of them a new instance of the dependency is created just once at Every HttpRequest (verified with a breakpoint into the constructor of the dependency and with the HashCode of the object).
Any ideas?
Thank you
#Travis gave good link to the documentation describing how it works. However, I prefer to give examples additionally to illustrate the theory better. So, let's take a look at simple example.
Suppose you have two classes ClassA and ClassB implementing some simple interfaces IClassA and IClassB.
public class ClassA : IClassA
{
public ClassA() {
}
}
public class ClassB : IClassB
{
public ClassB() {
}
}
Now, let's see what happens when we register them in different ways.
Example A
builder = new ContainerBuilder();
builder.RegisterType<ClassA>().As<IClassA>().InstancePerLifetimeScope();
builder.RegisterType<ClassB>().As<IClassB>().InstancePerLifetimeScope();
Then, in the controller, you do this:
public class HomeController : Controller
{
private readonly IClassA _classA;
private readonly IClassB _classB;
private readonly IComponentContext _ctx;
public HomeController(IClassA classA, IClassB classB, IComponentContext ctx) {
_classA = classA;
_classB = classB;
_ctx = ctx;
}
public string Get() {
using (var scope = _ctx.BeginLifetimeScope()) {
var newClassA = scope.Resolve<IClassA>(); // Object.ReferenceEquals(newClassA, _classA) == false
var newClassB = scope.Resolve<IClassB>(); // Object.ReferenceEquals(newClassB, _classB) == false
return "Ok";
}
}
}
In this example both 'new' variables in Get() method will receive new instances since they are both registered to be unique per lifetime scope. We began new lifetime scope - we got new instances.
Now, let's take a look at another example.
Example B
builder = new ContainerBuilder();
builder.RegisterType<ClassA>().As<IClassA>().InstancePerLifetimeScope();
builder.RegisterType<ClassB>().As<IClassB>().InstancePerRequest(); // now they have different life time!
// controller:
public class HomeController : Controller
{
private readonly IClassA _classA;
private readonly IClassB _classB;
private readonly IComponentContext _ctx;
public HomeController(IClassA classA, IClassB classB, IComponentContext ctx) {
_classA = classA;
_classB = classB;
_ctx = ctx;
}
public string Get() {
using (var scope = _ctx.BeginLifetimeScope()) {
var newClassA = scope.Resolve<IClassA>(); // Object.ReferenceEquals(newClassA, _classA) == false
var newClassB = scope.Resolve<IClassB>(); // Object.ReferenceEquals(newClassB, _classB) == true
return "Ok";
}
}
}
See what happened here? Even though we began new lifetime scope - ClassB still gets resolved from request scope and not from our new one. This is the difference between InstancePerLifetimeScope() and InstancePerRequest().
And as documentation suggests, internally it is based on another Autofac concept - InstancePerMatchingLifetimeScope().
In many cases it amounts to the same thing. This is an FAQ on the Autofac doc site.
I am creating a program for testing a website. Site has a registration process, which I am testing.
I have created a class named "Client", which should store the information about the client (name, family name, e-mail etc.).
Since I am testing, I use random number generator to generate a name for the client (I have the list of names, one of which is chosen randomly).
Obviously, I should create a method "generateName ()".
But the question is: in which class I should create it?
Lots of programmers would create the method in the Client class. And would do something like that:
client = new Client ();
client.generateName ();
But I have read, that this approach is incorrect - because the client does not generate name for himself. Program does.
Based on that information, I do as follows:
class Program
{
private void generateName ();
}
...
class Client
{
...
public void name ( String name )
{
this.name = name;
}
}
program = new Program ();
program.launch();
client = new Client ();
client.name ( program.generateName () );
But as I know, this approach is not used by the developers.
Could you clarify, how to know "what is right and what is wrong" here? And what information source should I use as an arbitrary for the cases of this kind?
It sounds like generateName() could be a static method in Client, since it's independent of instances:
class Client {
private String name;
public Client(String name) {
this.name = name;
}
public static String generateRandomName() {
String generatedName = ...;
return generatedName;
}
}
You could the simply pass it's value to the Client object as you currently are, or via the constructor:
client = new Client(Client.generateRandomName());
Otherwise, I'd suggest a ClientNameGenerator to handle name generation, to keep inline with SRP and to raise cohesion. This would be the better choice, seeing how you may be needing more name generation methods in the future:
class ClientNameGenerator {
public String generateRandomName() {
String generatedName = ...;
return generatedName;
}
//other name generation methods...
}
You can now use a ClientNameGenerator object to manage the generation of client names:
ClientNameGenerator nameGenerator = new ClientNameGenerator();
client = new Client(nameGenerator.generateRandomName());
Anytime you need to generate a name, simply use the ClientNameGenerator object you created.
There are a number of places which might be appropriate locations for this functionality.
You could have it as a private method on the Client class, used by a static factory method for generating Clients with a random name.
public class Client {
....
public static Client randomlyNamed() {
return new Client(randomName());
}
private static String randomName() {
return ...;
}
}
But that private method might be better extracted to a more appropriate class for generating random Strings...
public class Client {
private static final int defaultNameLength = 8;
....
public static Client randomlyNamed() {
return new Client(Strings.randomString(defaultNameLength));
}
}
public class Strings
private static String randomString(int length) {
return ...;
}
}
You could then expand the static method into a general purpose ClientBuilder class, with an instance method named something like 'withRandomName()'.
public class Client {
...
}
public class ClientBuilder {
private static final int defaultNameLength = 8;
...
public ClientBuilder randomlyNamed() {
this.name = Strings.randomString(defaultNameLength);
}
public Client build() {
return new Client(name);
}
}
public class Strings
private static String randomString(int length) {
return ...;
}
}
An alternative would be an implementation of a NamingStrategy (e.g. ``) object which is given to a ClientBuilder object.
public class RandomNames implements NamingStrategy {
private static final int defaultNameLength = 8;
public String name() {
return String.randomString(defaultNameLength);
}
}
public class ClientBuilder {
private final NamingStrategy nameSource;
public ClientBuilder(NamingStrategy nameSource) {
this.nameSource = nameSource;
}
public Client build() {
return new Client(nameSource.name());
}
}
The pure way to go would be to have a separate class ClientGenerator that produces clients. Because generating clients is not typical client behavior and in your application model a client is no more than a passive data container for client properties. However, generating clients is an activity in "the client domain". Therefor it would be defendable to create a static method Client.NewClient(), like the .NET feamework does with Guid. On the other hand, a guid's very nature is to be generated, it does not represent something in the real world. It IS a spawnable id. So the comparison may not be all that ligitimate.
A common similar mistake (or impurity if you wish) is a Save method on an object. Instead one should have a Persister class that does the job. Or a Manager. Because Save is something you can do to or with the class, not behavior of the class ifself.
Should not be needed create an instance of a class to access a public constant. I recently started working in Swift, so I must be missing something here.
In this simple example:
public class MyConstants{
public let constX=1;
}
public class Consumer{
func foo(){
var x = MyConstants.constX;// Compiler error: MyConstants don't have constX
}
}
This foo code gives an compile error. To work, I need to create an instance of the MyConstants like this:
public class Consumer{
func foo(){
var dummy = MyConstants();
var x = dummy.constX;
}
}
Adding static to constX is not allowed.
Use struct with static types.structare more appropriate as in enum you can only bind one type of associative values but you can contain the "Type Property of any type" in both.
public struct MyConstants{
static let constX=1;
}
public class Consumer{
func foo(){
var x = MyConstants.constX;
}
}
You should use immutable static variables. Unfortunately classes support computed properties only with the class modifier - the compiler outputs an error stating that class variables are not yet supported.
But in structs it's possible to create static data members:
struct Constants {
static let myConstant = 5
}
and of course it's not required to create an instance, as the immutable static property can simply be accessed as:
Constants.myConstant
If you want a constant, you can also "fake" the as-yet-unsupported class variable with a class computed property, which does currently work:
public class MyConstants{
public class var constX: Int { return 1 };
}
public class Consumer{
func foo(){
var x = MyConstants.constX; // Now works fine.
}
}
For string constants what I do is put the bunch of constants into responsible class file in the following way:
public enum NotificationMessage: String {
case kTimerNotificationId = "NotificationIdentifier"
}
Then for use it from any other point of the code just:
println("\(NotificationMessage.kTimerNotificationId.rawValue)")
Do not forget .rawValue.
I found out the solution below, but hope someone can clarify or post a better solution
enum MyConstantsV2 {
static var constX = 1
}
public class Consumerv2{
func foo(){
var x = MyConstantsV2.constX;
}
}
Is there a better way to consume a service in mvvmcross by constructor injection?
For example, I have my object in a plugin implementation
public class MyObject : IMyObject
{
public MyObject (int id)
{
_id = id;
}
}
and want to consume it somewhere the portable core (in the buisness layer) like this :
public void ConsumeTheService()
{
int i = 50;
var myObject = this.GetService<IMyObject>(i);
}
Actually, I only use a setter to get my id back in the implementation.
Following your update... if you are asking about how to get:
var myObject = this.GetService<IMyObject>(50);
and for this to return an object which is initiaised as new MyObject(50)
then I would instead recommend that you implement an interface
public interface IMyObjectFactory
{
IMyObject CreateMyObject(int i);
}
with an implementation:
public class MyObjectFactory : IMyObjectFactory
{
public IMyObject CreateMyObject(int i)
{
return new MyObject(i);
}
}
you can then register this IMyObjectFactory with IoC
I'm not sure I understand your example - not sure what intValue does in GetService
Regardless:
MvvmCross v3 includes constructor injection - see some details on http://slodge.blogspot.co.uk/2013/03/v3-new-viewmodel-lifecycle.html
Others have also implemented constructor injection within vNext - e.g. https://github.com/gshackles/CrossBar/ and http://slodge.blogspot.co.uk/2013/02/a-second-take-on-constructor-injection.html
The IoC within MvvmCross is completely replaceable - so you can use other IoC mechanisms if you want to (but this does require some code from you)
Since version 1.4.2 of XStream, the XStreamConverter annotation takes additional parameters (very good feature and just what I need).
#XStreamConverter(value=CustomXStreamConverter.class, strings={xyz"})
private List<String> phones;
But how can I read this values (xyz) in my custom converter?
public class CustomXStreamConverter implements Converter {
//?
}
I figure out the solution, just override the class constructor in order to receive the parameter.
public class CustomXStreamConverter implements Converter {
private String alias;
public ListToStringXStreamConverter(String alias) {
super();
this.alias = alias; //xyz
}
//...