![]() | |
![]() |
| | Thread Tools | Search this Thread | Display Modes |
#1
| |||
| |||
|
#2
| |||||
| |||||
|
|
Using the 2.0 framework, I'm trying to flesh out an idea that I had for a generic factory using an attribute to specify the type of concrete class that will be implemented. |
|
Our base factory does all the work and looks like this: abstract BaseFactory<TInterface, TConcreteImplementation { static TInterface Instance { get; } } Are you omitting the actual factory methods? That doesn't exactly make |
|
With subclasses implemented using code like this: FBusinessObject : BaseFactory<IBusinessObject, BusinessObject>{} Is this class supposed to have an Instance of type "IBusinessObject"? If so, |
|
[ConcreteImplementation(typeof(BusinessObject))] FBusinessObject : BaseFactory<IBusinessObject>{} then I could have clients of the factory only need to know about the assembly containing the interface and that containing the factory. Why do you need to mention "BusinessObject" at all at this point? Isn't the |
|
The problem is that I'm not finding a way to access the attributes of the subclass from within the base class. Any thoughts on how/if this can be done? You can use Object.GetType() to get the concrete type of the instance, and |
#3
| |||
| |||
|
|
You can use Object.GetType() to get the concrete type of the instance, and Type.GetAttributes() to get the attributes of that type. |
#4
| |||||
| |||||
|
|
Remember that it's totally irrelevant if it's neat in *theory*. A framework should be offering *practical* benefits. So now we've got the sermon out of the way, let's look at the actual issues. |
|
Are you omitting the actual factory methods? That doesn't exactly make things clearer. I'm assuming "Instance" is intended to be the factory instance, but then that's belied by this: |
|
Why do you need to mention "BusinessObject" at all at this point? Isn't the factory implementation the thing that has to deal with BusinessObjects eventually? Then let that take care of it and don't hoist this dependency to the general level, where it doesn't belong. The subclasses only responsibility is to tell the base class to which |
|
You can use Object.GetType() to get the concrete type of the instance, and Type.GetAttributes() to get the attributes of that type. I was trying to find a way to accomplish this from the static factory |
|
Kyle M. Burns wrote: Using the 2.0 framework, I'm trying to flesh out an idea that I had for a generic factory using an attribute to specify the type of concrete class that will be implemented. Be careful about ultra-genericity. It looks really neat on paper, but when you're finally done and take a step back you usally find out that you haven't actually gained any flexibility or safety that you couldn't have achieved with Plain Old Code, and you've atually saddled your clients with a big learning curve when they try to understand what the hell is going on (and they always eventually need to understand what the hell is going on, since the perfect framework exists only in dreams). I've fallen into this trap more than once. .NET makes it easy for you by having both generics and metadata. Remember that it's totally irrelevant if it's neat in *theory*. A framework should be offering *practical* benefits. So now we've got the sermon out of the way, let's look at the actual issues. Our base factory does all the work and looks like this: abstract BaseFactory<TInterface, TConcreteImplementation { static TInterface Instance { get; } } Are you omitting the actual factory methods? That doesn't exactly make things clearer. I'm assuming "Instance" is intended to be the factory instance, but then that's belied by this: With subclasses implemented using code like this: FBusinessObject : BaseFactory<IBusinessObject, BusinessObject>{} Is this class supposed to have an Instance of type "IBusinessObject"? If so, how is this a factory? "BusinessObject" could implement the singleton pattern itself. Don't you mean it has to have an Instance field of type "FBusinessObject"? The *factory* being a singleton would make more sense (even though there's still no reason why you should decide that all factories have to be singletons!) I hope "Instance" isn't supposed to be the thing that returns multiple different objects! Using a property for that is totally inappropriate. [ConcreteImplementation(typeof(BusinessObject))] FBusinessObject : BaseFactory<IBusinessObject>{} then I could have clients of the factory only need to know about the assembly containing the interface and that containing the factory. Why do you need to mention "BusinessObject" at all at this point? Isn't the factory implementation the thing that has to deal with BusinessObjects eventually? Then let that take care of it and don't hoist this dependency to the general level, where it doesn't belong. You seem to have created the problem for yourself by insisting that a super-generic base class contain it all. This doesn't actually help the subclasses. For example, how is this base class supposed to know how to instantiate concrete classes? Haven't you locked yourself into a design where all objects must have a default constructor or some other "one size fits all" creation pattern? What's the benefit there, and how would it hurt subclasses to have to write out that construction themselves? The problem is that I'm not finding a way to access the attributes of the subclass from within the base class. Any thoughts on how/if this can be done? You can use Object.GetType() to get the concrete type of the instance, and Type.GetAttributes() to get the attributes of that type. So: abstract BaseFactory<...> { public void Foo() { ConcreteImplementationAttribute cia = (ConcreteImplementationAttribute) Attribute.GetCustomAttribute(this.GetType(), typeof(ConcreteImplementationAttribute)); // Use cia here } } The usual caveats apply: reflection is slow when not carefully applied and adds to maintenance costs by introducing hidden dependencies. In this case, it really doesn't seem worth it. You're writing more framework code than code that actually *does* something, and it doesn't seem to give you anything in the way of reusability and flexibility. If all you're trying to do is saving the clients from writing what appears to be one line of code, don't bother. -- J. |
#5
| ||||
| ||||
|
|
Remember that it's totally irrelevant if it's neat in *theory*. A framework should be offering *practical* benefits. So now we've got the sermon out of the way, let's look at the actual issues. We're not talking theory here, but a set of objects that share a common creation strategy in a distributed COM+ environment where logging and other corrective measures to ensure the client obtains an instance of the object need to be taken. |
|
The approach originally recommended by Microsoft was a factory object with the interface described earlier that implements more than a few lines in the actual factory method and needs to be applied to every one of our factories. So you have share functionality (actually, it sounds more like *identical* |
|
Why do you need to mention "BusinessObject" at all at this point? Isn't the factory implementation the thing that has to deal with BusinessObjects eventually? Then let that take care of it and don't hoist this dependency to the general level, where it doesn't belong. The subclasses only responsibility is to tell the base class to which interface Instance must conform and which concrete class will be used in the creation, so this is the only point in the creation process in which BusinessObject matters at all. Alright, I have a clearer picture of what you're trying to achieve now. |
|
You can use Object.GetType() to get the concrete type of the instance, and Type.GetAttributes() to get the attributes of that type. I was trying to find a way to accomplish this from the static factory method, but it looks like I may need "this" in order to obtain the attributes. Yes, you will. But there doesn't seem to be any pressing reason to muck |
#6
| |||
| |||
|
|
Using the 2.0 framework, I'm trying to flesh out an idea that I had for a generic factory using an attribute to specify the type of concrete class that will be implemented. Our base factory does all the work and looks like this: abstract BaseFactory<TInterface, TConcreteImplementation { static TInterface Instance { get; } } With subclasses implemented using code like this: FBusinessObject : BaseFactory<IBusinessObject, BusinessObject>{} A big problem with this is that it creates a compile time dependency between the consumer of the interface and the assembly containing the concrete implementation. My thought was that if I could change the BaseFactory to look like this: abstract BaseFactory<TInterface { static TInterface Instance { get; } } and subclasses to look like: [ConcreteImplementation(typeof(BusinessObject))] FBusinessObject : BaseFactory<IBusinessObject>{} then I could have clients of the factory only need to know about the assembly containing the interface and that containing the factory. The problem is that I'm not finding a way to access the attributes of the subclass from within the base class. Any thoughts on how/if this can be done? |
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
| |