So let´s assume we have a Base-Assembly and a Custom-Assembly where every type within Base may or may not be overridden. So I have some code that creates a deep nested structure of some base-types. Now if I want to overwrite just some single type within this structure I would have to overwrite the whole structure to instantiate it. To ease this process I use a factory (as proposed here) that builds my inner-types.
public class MyFactory
{
private Assembly _customAssembly = // get custom-assembly;
private Type _actualType = null;
private static MyFactory _instance = new MyFactory();
private MyFactory()
{
// if we have custom assembly we search for classes that derive from our base-type
if (this._customAssembly != null) this._actualType = this._customAssembly.GetTypes().SingleOrDefault(x => x.BaseType == typeof(MyClass));
// no derived type found so use the base-type
if (this._actualType == null) this._actualType = typeof(MyClass);
}
/// <summary>
/// Gets an instance of either <see cref="MyClass"/> or an instance of a derived type of this class if there is any within the custom-assembly
/// </summary>
public static MyClass Create(string name) { return (MyClass)Activator.CreateInstance(MyFactory._instance._actualType, name); }
}
Now I can call the factory-method within my base-interface to create an inner-type. If this inner-type was derived within my custom-assembly I get an instance of that type instead of the base-type.
Now my question: As far as I know creating instances via reflection may take some time. Hence I´m creating such instances within a loop this may become a performance-relevant issue. I know that you may pimp up speed for invoking methods by using LINQ-Expressions (although I never did on my own). that point to the actual method. Thus we can directly invoke the method which may be much faster then using MethodInfo.Invoke. Is there any similar approach I can use to create new instances by declaring some kind of pointer to a constructor rather then a method?
Thanks for ya :)
You can use generics to do this:
public class MyFactory<T> where T : MyBaseClass
{
public static T Create(string name) { return new T{ Name = name }; }
}
Related
I have a base class DataSet and several derived classes (DataSetSeries, DataSetTable, ...). The constructors of the derived classes each take exactly one argument the type of which is specific to the derived class, e.g.
public DataSetSeries(Series s);
public DataSetTable(Table t);
I have written a (generic) factory class that allows me to create instances of DataSet subclasses from the corresponding original data types, e.g.
DataSet aDataSetSeries = DataSet.Factory.Create(aSeries);
DataSet aDataSetTable = DataSet.Factory.Create(aTable);
where DataSet.Factory is a static readonly field of DataSet. What Create does is determine the type of its argument, then try to lookup the corresponding constructor delegate (which has been registered before) from a dictionary and execute the delegate if it exists.
So I have to register each of the derived classes' constructors at the factory. In order to keep similar things close together and not to forget to add the registration for any new DataSet subclass, I wanted to do this registration in the derived DataSet-classes instead of DataSet itself (which isn't supposed to know any of its derived classes in a strict OO sense). Because Factory is static, I am trying to include a static constructor in each derived DataSet, e.g.
public class DataSetSeries: DataSet
{
static DataSetSeries()
{
Factory.Register(typeof(Series), data => new DataSetSeries((Series)data));
}
// ...
}
But now here is my problem: the static constructor of DataSetSeries will only be called upon first usage of DataSetSeries. But the first thing I will do is call DataSet.Factory.Create(aSeries), which is not a method of DataSetSeries and so there is no first usage of DataSetSeries at all. Hence the static constructor will never be called.
How could I get this working without explicitely iterating over all derived types (which was the reason for setting up the factory in the first place)?
You can create a static constructor for factory and inside this constructor can find all sub-classes of Dataset (DataSetSeries, DataSetTable, ...). and call static constructor for them.
public static class Factory
{
static Factory()
{
var datasetDerrivedTypes = Assembly
.GetExecutingAssembly()
.GetTypes()
.Where(t => typeof(DataSet).IsAssignableFrom(t) &&
t != typeof(DataSet));
foreach (var type in datasetDerrivedTypes)
{
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
}
}
public static void Register(Type type, Func<Series, DataSet> constructorDelegate)
{
}
}
I'm trying to refactor a method that parses through a file. To support files of arbitrary size, the method using a chunking approach with a fixed buffer.
public int Parse()
{
// Get the initial chunk of data
ReadNextChunk();
while (lengthOfDataInBuffer > 0)
{
[parse through contents of buffer]
if (buffer_is_about_to_underflow)
ReadNextChunk();
}
return result;
}
The pseudo code above is part of the only public non-static method in a class (other than the constructor). The class only exists to encapsulate the state that must be tracked while parsing through a file. Further, once this method has been called on the class, it can't/shouldn't be called again. So the usage pattern looks like this:
var obj = new MyClass(filenameToParse);
var result = obj.Parse();
// Never use 'obj' instance again after this.
This bugs me for some reason. I could make the MyClass constructor private, change Parse to a static method, and have the Parse method new up an instance of Parse scoped to the method. That would yield a usage pattern like the following:
var result = MyClass.Parse(filenameToParse);
MyClass isn't a static class though; I still have to create a local instance in the Parse method.
Since this class only has two methods; Parse and (private) ReadNextChunk, I'm wondering if it might not be cleaner to write Parse as a single static method by embedding the ReadNextChunk logic within Parse as an anonymous method. The rest of the state could be tracked as local variables instead of member variables.
Of course, I could accomplish something similar by making ReadNextChunk a static method, and then passing all of the context in, but I remember that anon methods had access to the outer scope.
Is this weird and ugly, or a reasonable approach?
This maybe suitable more to code review.
However, these are my comments about your design:
I don't think it will matter much about obj instance only used once. If you bugged with it, there are 2 ways to trick it:
Use of another method such as:
public int Parse()
{
var obj = new MyClass(filenameToParse);
return obj.Parse();
}
Make the MyClass implement IDisposable and wrap it in using statement. I don't recommend this since usually IDisposable has logic in their Dispose() method
I think it is better to make your MyClass accept parameter in Parse to Parse(string fileNameToParse). It will make MyClass as a service class, make it stateless, reusable and injectable.
Regarding impact to static class. First it add coupling between your consumer and MyClass. Sometimes if you want to test / unit test the consumer without using the MyClass parser, it will be hard / impossible to mock the MyClass into something you want.
All you need is a static parse method that creates an instance, much like what you suggest in your question
public class MyClass
{
// your existing code.... but make the members and constructor private.
public static int Parse(string filenameToParse)
{
return new MyClass(filenameToParse).Parse();
}
}
then
just use it like you suggest...
var result = MyClass.Parse(filenameToParse);
MyClass isn't a static class though; I still have to create a local
instance in the Parse method.
You don't need a static class to be able to leverage static methods. For example this works fine:
public class MyClass
{
public static string DoStuff(string input)
{
Console.WriteLine("Did stuff: " + input);
return "Did stuff";
}
}
public class Host
{
public void Main()
{
MyClass.DoStuff("something");
}
}
I have a problem with declaring a type as passed from parameter type variable.
public static void ShowThisForm(Type passXtraForm, Form parent)
{
var xfrm = passXtraForm.GetType();
xfrm xfrmName = new xfrm();
xfrmName.Show();
}
Can I declare a variable as a type from passXtraForm.GetType() and declare it to another variable? Just passing the type of form to another class.
Thanks in advance for the response.
you could use generics for this:
public static void ShowThisForm<T>(T passXtraForm, Form parent) where T : Form, new()
{
T xfrmName = new T();
xfrmName.Show();
}
in this case the type argument is restricted to the Form type and types deriving from Form.
anyway, why are you having this method? there are other methods in the Form and Application static classes for finding the forms out there in your app...
First of all, it doesn't look like you need the parent parameter; I'd eliminate it entirely. Then I'd use generics to do what you're trying to accomplish:
public static void ShowThisForm<T>() where T : Form, new()
{
T xfrmName = new T();
xfrmName.Show();
}
The where T : Form, new() portion of this code is called a type constraint and it prevents you from calling the ShowThisForm method with a type that doesn't have a default constructor and derive from Form.
By indicating that T must have a default constructor, the compiler knows how to resolve new T(); by indicating that T derives from Form, the compiler knows how to call the .Show() method.
So, if you have a form class called MyForm, you could use the following syntax to call this method:
ShowThisForm<MyForm>();
For more documentation, you should take a look at these articles on MSDN:
Generic Methods
Constraints on Type Parameters
You could change it to something more like this:
public static void ShowThisForm<T>() where T : Form, new()
{
T xfrmName = new T();
xfrmName.Show();
}
Maybe pass in a factory, so that a known interface can instantiate what ever type of object the calling code deems is necessary?
(the below code is a quick sample I typed in here; formatting is off, and design could be better. It's just to give an idea)
static class XFactory
{
private int _id;
public XFactory(int formId) {
_id = formId;
}
/// <summary>
/// Decides which class to instantiate.
/// </summary>
public static Form Get()
{
switch (_id)
{
case 0:
return new FormA();
case 1:
case 2:
return new FormB();
case 3:
default:
return new FromC();
}
}
}
public static void Main()
{
ShowThisForm(new XFactory(2));
}
public static void ShowThisForm(XFactory formFactory)
{
var xfrm = formFactory.Get();
xfrm.Show();
}
You can instantiate a class/type via reflection and Activator.CreateInstance(typ, constructorargs), but most likely it would be better to create the object elsewhere and have it be of either a known base class (in your case it looks like form), or have it implement a defined interface that can be used to manipulate it. Very rarely will you need to create an object of totally unknown type.
I have a class with internal constructor and want to Resolve it from Unity (2.0).
public class MyClass {
internal MyClass(IService service) {
}
}
then I'm doing
_container.Resolve<MyClass>();
when I do so I have an exception
Exception is: InvalidOperationException - The type MyClass cannot be constructed.
IService is registered and the only problem is that constructor is internal.
I really want this class to be public, but I want it to be creatable only via a factory (in which I'm actually calling container.Resolve<MyClass>()).
Is there a way to make Unity see that internal constructor? Like InternalsVisibleTo or something?
I dug a little into how you might extend Unity for this purpose, and found some interesting information.
First, it seems that Unity selects which constructor to use by internally resolving an IConstructorSelectorPolicy. Included in Unity is the public abstract class ConstructorSelectorPolicyBase<TInjectionConstructorMarkerAttribute>, which includes this gem:
/// <summary>
/// Choose the constructor to call for the given type.
/// </summary>
/// <param name="context">Current build context</param>
/// <param name="resolverPolicyDestination">The <see cref='IPolicyList'/> to add any
/// generated resolver objects into.</param>
/// <returns>The chosen constructor.</returns>
public SelectedConstructor SelectConstructor(IBuilderContext context, IPolicyList resolverPolicyDestination)
{
Type typeToConstruct = context.BuildKey.Type;
ConstructorInfo ctor = FindInjectionConstructor(typeToConstruct) ?? FindLongestConstructor(typeToConstruct);
if (ctor != null)
{
return CreateSelectedConstructor(context, resolverPolicyDestination, ctor);
}
return null;
}
FindInjectionConstructor and company are private static methods in this class which ultimately end up calling Type.GetConstructors (the overload with no parameters, which only returns public constructors). This tells me that if you can arrange for Unity to use your own constructor selector policy, which would be able to select any constructor, you are golden.
There is good documentation about how to make and utilize your own container extensions, so I imagine it's quite possible to make your own CustomConstructorSelectorPolicy that includes the relevant portions of DefaultUnityConstructorSelectorPolicy (which derives from the abstract base class and is the default unless you register something else) and ConstructorSelectorPolicyBase (deriving from this directly would probably not work well because key methods are not virtual, but you can reuse the code).
Therefore I 'd say it's doable with a moderate amount of hassle, but the end result would be quite "pure" from an engineering point of view.
Unity will only look at public constructors, so you need to make this constructor public.
I really want this class to be public,
but I want it to be creatable only via
a factory
In that case, create a factory:
public class MyClassFactory : IMyClassFactory
{
private readonly IService service;
public MyClassFactory(IService service)
{
this.service = service;
}
MyClass IMyClassFactory.CreateNew()
{
return new MyClass(this.service);
}
}
And register:
_container.Register<IMyClassFactory, MyClassFactory>();
And resolve:
_container.Resolve<IMyClassFactory>().CreateNew();
You can also use Unity's InjectionFactory:
container.Register<MyClass>(new InjectionFactory(c =>
{
return new MyClass(c.Resolve<IService>());
}));
For this to work the assembly that holds this code should be able to see the internals of the assembly that holds the MyClass. In other words the MyClass assembly should be marked with InternalsVisibleTo.
What would also work is the following:
public static class MyClassFactory
{
public static MyClass CreateNew(IService service)
{
return new MyClass(service);
}
}
container.Register<MyClass>(new InjectionFactory(c =>
{
return MyClassFactory.Create(c.Resolve<IService>());
}));
Although you won't have to make the constructor public, it is a great way to obfuscate your code :-)
Just make the class internal and the constructor public...
Interface public
Class internal
Constructor of class public.
It's possible there are workarounds/hacks that would allow you to do this with Unity 9I don't know if any), but in general if you want a class to be managed by Unity (or any IOC container), it needs to be public with a public constructor.
One option might be to make an abstract factory that creates the class that has a public constructor, and keep the class's constructor internal. The downside is then your factory will be managed by Unity, but your class itself will not.
All I need is a way to make a property of one class only 'settable' from one other class (a sort of manager class).
Is this even possible in c#?
My colleague 'reliably' informs me that I have a design flaw, but I feel I should at least ask the community before I concede defeat!
No, it's not really possible to do this in any clean way in C#. You probably have a design flaw ;-)
You can use the internal modifier, which lets all types in the same assembly access the data (or nominated assemblies if using [InternalsVisibleTo] - but no: there is no friend equivalent in C#.
For example:
public string Foo {get; internal set;}
You have a design flaw. Also, don't be paranoid about data hiding. Here's 3.5's way to do it:
class Program
{
static void Main(string[] args)
{
Managed m = new Managed();
Console.WriteLine(m.PrivateSetter);
m.Mgr.SetProperty("lol");
Console.WriteLine(m.PrivateSetter);
Console.Read();
}
}
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(s => PrivateSetter = s)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
}
public class Manager
{
private Action<string> _setPrivateProperty;
public Manager(Action<string> setter)
{
_setPrivateProperty = setter;
}
public void SetProperty(string value)
{
_setPrivateProperty(value);
}
}
Here's how we'd do it in pre-lambda days:
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(this)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
public class Manager
{
public void SetProperty(string value)
{
m.PrivateSetter = value;
}
private Managed m;
public Manager(Managed man)
{
m = man;
}
}
}
The best way to do it would be:
/// <summary>
/// Gets or sets foo
/// <b>Setter should only be invoked by SomeClass</b>
/// </summary>
public Object Foo
{
get { return foo; }
set { foo = value; }
}
When you have some complex access or inheritance restriction, and enforcing it demands too much complexity in the code, sometimes the best way to do it is just properly commenting it.
Note however that you cannot rely on this if this restriction has some security implications, as you are depending on the goodwill of the developer that will use this code.
You cannot do that on that way, but you can access a property's setter method from a derived class, so you can use inheritance for the purpose. All you have to do is to place protected access modifier. If you try to do so, your colleague is right :). You can try doing it like this:
public string Name
{
get{ return _name; }
protected set { _name = value; }
}
keep in mind that the set method of the property is only accessible from the derived class.
Or you could have these two classes in an assembly alone and have the setter as internal. I would vote up for the design flaw though, unless the previous answer by milot (inheriting and protected) makes sense.
You could do:
public void setMyProperty(int value, Object caller)
{
if(caller is MyManagerClass)
{
MyProperty = value;
}
}
This would mean that you could use a 'this' pointer from the calling class. I would question the logic of what you're attempting to achieve, but without knowing the scenario I can't advise any futher. What I will say is this: if it is possible to refactor your code to make it clearer, then it is often worthwhile doing so.
But this is pretty messy and certinly NOT fool-proof ... you have been warned!
Alternativly...
You could pass a delegate from the Class with the Property (Class A) to the Manager Class (Class B). The delegate can refer to a private function within A to allow B to call that delegate as any normal function. This precludes that A knows about B and potentially that A is created before B. Again... messy and not fool-proof!
You can achieve to this by making a Public property in your "settable class" that will inherit from the real class that will have a protected property... this way only the inherit class can SET and not class that doesn't inherit. But the drawback is that you will require to have an inherit class...
Reflection, though I would agree that having to do this just to get around an access modifier is probably an indication of a bad design.
public class Widget
{
private int count;
public int Count
{
get { return this.count; }
private set { this.count = value; }
}
}
public static class WidgetManager
{
public static void CatastrophicErrorResetWidgetCount( Widget widget )
{
Type type = widget.GetType();
PropertyInfo info = type.GetProperty("Count",BindingFlags.Instance|BindingFlags.NonPublic);
info.SetValue(widget,0,null);
}
}
The reason this is a design flaw is because it seems muddled between the scope of the two objects.
The properties of a class should be accessible in the context of that class, at least internally.
It sounds like the settable property on your item class is really a property of the manager class.
You could do something similar to what you want by closely coupling the two classes:
public class MyItem {
internal MyItemManager manager { get;set; }
public string Property1 {
get { return manager.GetPropertyForItem( this ); }
}
}
Unfortunately this isn't great design either.
What your looking for is what C++ calls a Friend class but neither c# or vb has this functionality. There is a lot of debate as to the merit of such functionality since it almost encourages very strong coupling between classes. The only way you could implement this in c# would be with reflection.
If your goal is to have a class Foo let some property (e.g. Bar, of type Biz) to be changed by some other object, without exposing it publicly, a simple way to do that is to have an instance of Foo which is supposed to be changeable by some other object to pass that other object an Action<Biz> which points to a private method that changes Bar to the passed-in value. The other object may use that delegate to change the Bar value of the object that supplied it.
If one wishes to have give all instances of some type Woozle the ability to set the Bar value of any instance of Foo, rather than exposing such abilities on a per-instance basis, one may require that Woozle have a public static method Woozle.InstallFooBarSetter which takes a parameter of type Action<Foo, Biz> and one of type Object. Foo should then have a static method WoozleRequestBarSetter which takes an Object, and passes it to Woozle.InstallFooBarSetter along with an Action<Foo,Biz>. The class initializer for Woozle should generate a new Object, and pass it to Foo.RequestBarSetter; that will pass the object to Woozle.InstallFooBarSetter along with a delegate. Woozle can then confirm that the passed-in object is the one that it generated, and--if so--install the appropriate delegate. Doing things this way will ensure that nobody but Woozle can get the delegate (since the delegate is only passed to Woozle.InstallFooBarSetter), and Woozle can be sure its delegate comes from Foo (since nobody else would have access to the object that Woozle created, and Woozle.InstallFooBarSetter won't do anything without it).
if it is a design flaw depends on what you want to do. You could use the StackTrace class from System.Diagnostics to get the Type of the class setting your property and then compare to the type you want to allow setting yor property..but maybe there are better ways for performing something like this (e.g. boxing)