Factory Pattern: Determining concrete factory class instantiation? - c#

I'm trying to learn patterns and I'm stuck on determining how or where a Factory Pattern determines what class to instanciate. If I have a Application that calls the factory and sends it, say, an xml config file to determine what type of action to take, where does that logic for interpreting the config file happen?
THE FACTORY
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace myNamespace
{
public abstract class SourceFactory
{
abstract public UploadSource getUploadSource();
}
public class TextSourceFactory : SourceFactory
{
public override UploadSource getUploadSource()
{
return new TextUploadSource();
}
}
public class XmlSourceFacotry : SourceFactory
{
public override UploadSource getUploadSource()
{
return new XmlUploadSource();
}
}
public class SqlSourceFactory : SourceFactory
{
public override UploadSource getUploadSource()
{
return new SqlUploadSource();
}
}
}
THE CLASSES
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace myNamespace
{
public abstract class UploadSource
{
abstract public void Execute();
}
public class TextUploadSource : UploadSource
{
public override void Execute()
{
Console.WriteLine("You executed a text upload source");
}
}
public class XmlUploadSource : UploadSource
{
public override void Execute()
{
Console.WriteLine("You executed an XML upload source");
}
}
public class SqlUploadSource : UploadSource
{
public override void Execute()
{
Console.WriteLine("You executed a SQL upload source");
}
}
}

The actual factory to instantiate is selected at runtime, often by a separate factory loader class. The loader may get the necessary configuration, e.g. in an xml config file, and read from it the class name of the concrete factory to load.
This in itself is not a very complicated logic; the reason to put it into a factory loader class is reusability. You can have many factories in your app, and often, most of the factory loading code is pretty similar, so putting it into a separate class (hierarchy) eliminates code duplication. And of course, the logic may be different and more complicated than this example.
E.g. a more dynamic scenario would be to specify a mapping between buttons / menu items and class names in the xml file, then on the GUI, the user could change the factory to be used by pressing a button / selecting a menu item.

Related

Multiple CollectionDefinition per test class in XUnit

We have many XUnit tests in our project that we use to test our API (each with many InlineData). The problem is that we can access a subset of the API via two other connection methods.
Today we use a CollectionDefinition to keep the connection to the main API (it is time consuming to create the connection) and we intend to have three separate CollectionDefinition, one for each connection path.
I imagine I will create a new attribute I can add to each test class to tell which connection methods it should use. And then it uses the CollectionDefinitions that are connected to the various connections.
I am considering using [assembly: Xunit.TestFramework ("name", "assembly")] and implementing my own XunitTestFramework. But I can not figure out how to achieve what I want. Do you have any suggestions on how I should proceed?
You can accomplish this as follows:
Make an abstract class that defines the methods common to all your API's, and derive specific classes from it which create the specific connection. Make a CollectionDefinition and a fixture for each type of connection:
using Xunit;
namespace SO71300821_multipleCollectionDefinition
{
public abstract class APIConnectionMethod
{
public bool isOK { get; } = true;
};
public class APIConnectionMethod0 : APIConnectionMethod
{
public APIConnectionMethod0()
{
// ... initialize API connection ...
}
}
[CollectionDefinition("Collection0")]
public class Collection0 : ICollectionFixture<APIConnectionMethod0>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
}
public class APIConnectionMethod1 : APIConnectionMethod
{
public APIConnectionMethod1()
{
// ... initialize API connection ...
}
}
[CollectionDefinition("Collection1")]
public class Collection1 : ICollectionFixture<APIConnectionMethod1>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
}
public class APIConnectionMethod2 : APIConnectionMethod
{
public APIConnectionMethod2()
{
// ... initialize API connection ...
}
}
[CollectionDefinition("Collection2")]
public class Collection2 : ICollectionFixture<APIConnectionMethod2>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
}
}
Make an abstract base test class that implements all the tests that need to work for each of the various API's:
using Xunit;
namespace SO71300821_multipleCollectionDefinition
{
public abstract class UnitTestBase
{
APIConnectionMethod connection;
public UnitTestBase(APIConnectionMethod connection_)
{
connection = connection_;
}
[Fact]
public void connectionIsOK()
{
Assert.NotNull(connection);
Assert.True(connection.isOK);
}
}
}
Derive a public class from the base test class for each type of connection:
using Xunit;
namespace SO71300821_multipleCollectionDefinition
{
[Collection("Collection0")]
public class UnitTestSpecific0 : UnitTestBase
{
public UnitTestSpecific0(APIConnectionMethod0 connection_) : base(connection_)
{
}
}
[Collection("Collection1")]
public class UnitTestSpecific1 : UnitTestBase
{
public UnitTestSpecific1(APIConnectionMethod1 connection_) : base(connection_)
{
}
}
[Collection("Collection2")]
public class UnitTestSpecific2 : UnitTestBase
{
public UnitTestSpecific2(APIConnectionMethod2 connection_) : base(connection_)
{
}
}
}
If there are tests that only work for certain specific types of connections, you can implement them in these classes.
The test discoverer will find the tests in UnitTestBase in each of the derived classes and run them in those classes, so you'll have a separate test in the Test Explorer for each of the derived classes.
The information from https://xunit.net/docs/shared-context helped me prepare this answer and some of the code is copied from there.

Why is my Windsor Container saying it can't resolve this dependency even though it can?

Given the following code:
using Castle.DynamicProxy;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using System;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
WindsorContainer container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Classes.FromThisAssembly()
.BasedOn<IAuditInterceptor>()
.WithServiceDefaultInterfaces()
.LifestyleTransient());
container.Register(Classes.FromThisAssembly()
.BasedOn(typeof(ICommandHandler<>))
.WithServiceAllInterfaces()
.Configure(c => c.Interceptors<IAuditInterceptor>().LifestyleTransient()));
container.Register(Component.For<ICommandHandlerFactory>().AsFactory());
var factory = container.Resolve<ICommandHandlerFactory>();
var handlers = factory.GetHandlersForCommand<DummyCommand>();
handlers.First().Handle(new DummyCommand());
}
}
public interface IAuditInterceptor : IInterceptor
{
}
public interface ICommand
{
}
public interface ICommandHandler<T> where T : ICommand
{
void Handle(T command);
}
public interface ICommandHandlerFactory
{
ICommandHandler<T>[] GetHandlersForCommand<T>() where T : ICommand;
}
public class DummyCommand : ICommand
{
}
public class DummyCommandHandler : ICommandHandler<DummyCommand>
{
public void Handle(DummyCommand command)
{
Console.WriteLine("Hello from command handler");
}
}
public class AuditInterceptor : IAuditInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Interceptor before");
invocation.Proceed();
Console.WriteLine("Interceptor After");
}
}
}
The code runs and executes as expected, and the interceptor fires and the program completes normally. However, if you do a check for potentially misconfigured components, you get told that
Some dependencies of this component could not be statically resolved.
'ConsoleApplication1.DummyCommandHandler' is waiting for the following
dependencies:
- Component 'ConsoleApplication1.IAuditInterceptor' (via override) which was not found. Did you forget to register it or misspelled the
name? If the component is registered and override is via type make
sure it doesn't have non-default name assigned explicitly or override
the dependency via name.
What causes this? The code runs and executes without problem. Why does Windsor say it can't find IAuditInterceptor?
This goes away if you remove the injection of IAuditInterceptor and register the concrete type AuditInterceptor by itself, like this:
container.Register(Component.For<AuditInterceptor>().LifestyleTransient());
container.Register(Classes.FromThisAssembly()
.BasedOn(typeof(ICommandHandler<>))
.WithServiceAllInterfaces()
.Configure(c => c.Interceptors<AuditInterceptor>().LifestyleTransient()));

Implementing Interface using extension methods in c#

I have an Interface:
public interface IMessager
{
void ShowMessage();
}
Is there any way to implement this interface using extension methods?
public static class Extensions
{
public static void ShowMessage(this MyClass e)
{
Console.WriteLine("Extension");
}
}
and a class that implement it:
public class MyClass:IMessager
{
public void ShowMessage()
{
ShowMessage(); // I expect that program write "Extension" in console
}
}
But when I run the program I get the System.StackOverflowException.
The code you posted is just a method calling itself recursively (hence the StackOverflowException).
I'm not entirely sure what you're trying to accomplish but to answer your question
Is there any way to implement this interface using extension methods?
No.
To be a bit more pragmatic about this though, if your aim is to only write your method once you have a few options:
1. Call the extension explicitly
public class MyClass:IMessager
{
public void ShowMessage()
{
Extensions.ShowMessage(this);
}
}
although as pointed out in comments, this basically defeats the point of using the extension method. Additionally there is still "boiler-plate code" such that every time you implement your interface you have to call the static method from within the method (not very DRY)
2. Use an abstract class instead of an interface
public abstract class MessengerBase
{
public void ShowMethod() { /* implement */ }
}
public class MyClass : MessengerBase {}
...
new MyClass().ShowMethod();
This issue with this though is that you can't inherit from multiple classes.
3. Use extension on the interface
public interface IMessenger { /* nothing special here */ }
public class MyClass : IMessenger { /* also nothing special */ }
public static class MessengerExtensions
{
public static void ShowMessage(this IMessenger messenger)
{
// implement
}
}
...
new MyClass().ShowMessage();

How to make an object belong to a namespace (VS 2008)?

I have a name space Company.Controls, which contains several controls. I also have a class called "Common" which contains enums/structures/static methods that I use throughout the controls.
Is there a way to make these "Common" peices belong to the Company.Controls namespace this way I don't have to keep typing "Common.Structure"? Essentially having he "Common" both a namespace and a class.
Just seems messy and confusing when reading the code.
example (all the other controls are in the Blah.Controls.Common namespace)
namespace Blah.Controls
{
public enum ControlTouchState
{
Down = 0x00,
Up = 0x01,
}
public Common()
{
//Stuff here
}
}
Thanks.
You can't get exactly what you want; in C# all methods have to be in a class.
Depending on what is in your Common class, you might be able to find something a slightly more satisfying by using extension methods:
namespace Blah.Controls
{
public class CommonControl { }
public static class Common
{
public static void Foo(this CommonControl cc) { }
}
public class Control1 : CommonControl
{
public void Bar()
{
this.Foo();
}
}
}
Another thing you might consider is using partial classes which would let you write simple wrappers elsewhere:
namespace Blop.Controls
{
public static class Common
{
public static void Foo() { }
}
public partial class Control1
{
public void Bar()
{
Foo();
}
}
public partial class Control1
{
public void Foo()
{
Common.Foo();
}
}
}
Obviously, introducing some inheritence could eliminate some of the duplication; I'm assuming you don't want to do that.
Is there some reason that the nested types in Common MUST be nested? Why not separate them out into their own namespace?
namespace Common
{
public struct Structure
{
// ...
}
public enum Enumeration
{
// ...
}
public class Common
{
// ...
}
}
You could then use the Common namespace as such:
namespace Blah.Controls
{
using Common;
class Control
{
Struct myStruct;
Enumeration myEnum;
Common myCommon; // references the class, not the namespace
}
}

Unable to Get data from DA layer. What to do?

While dividing my C# application in layers, I have solved the problem of circular dependency among layers in the following way:
using System;
using System.Collections.Generic;
using System.Text;
using SolvingCircularDependency.Common;
using SolvingCircularDependency.DA;
namespace SolvingCircularDependency.BO
{
public class MyClass : IPersistent
{
private string _message;
public string Message
{
get { return _message; }
set { _message = value; }
}
public bool Save()
{
return MyClassDA.Save(this);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace SolvingCircularDependency.Common
{
public interface IPersistent
{
bool Save();
string Message { get;}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using SolvingCircularDependency.Common;
namespace SolvingCircularDependency.DA
{
public class MyClassDA
{
public static bool Save(IPersistent obj)
{
Console.WriteLine(obj.Message);
return true;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using SolvingCircularDependency.BO;
namespace SolvingCircularDependency.UI
{
class Program
{
static void Main(string[] args)
{
MyClass myobj = new MyClass();
myobj.Message = "Goodbye Circular Dependency!";
myobj.Save();
Console.ReadLine();
}
}
}
Please take a look at the class MyClassDA in the DA layer and the assembly itself.
How can a MyDA.Get() method return objects of type MyClass when the Data Access layer doesn't know about the MyClass type.
If this design is not efficient, How can I change/modify it?
As far as I can understand you have a bidirectional relationship between your DA and Business layer.
To solve this problem I suggest that you should have 3 layers instead of two. I mean you should have a Model layer that simply model the DB objects ,then you can derive from model classes in your Business layer and add other behaviors like Save method.
Here's what I mean:
//Model Layer
public class UserModel
{
public virtual string Firstname{get;set;}
}
//DataAccess Layer
public class UserDao
{
List<UserModel> GetAll();
}
//BusinessLayer
public class UserDomainModel:UserModel
{
public UserDomainModel(UserModel user,UserDao dao)
{
_user=user;
_dao=dao;
}
public override string FirstName
{
get
{
return _user.FirstName;
}
set
{
_user.FirstName=value;
}
public void Save()
{
_dao.Save(_user);
}
}
}
I'm using a decorator to combine User and UserDao as a domain model object.
One of the reasons people do Persistance Ignorant objects (POCO) is to avoid such a scenario. There is simply no way for the data access layer to have a reference to a class that it doesn't know about - it is much better to have the class not know about the data access.
The only way you can really do this is to implement Get() on User instead of on UserDA. You can do something like this:
public class User {
IGetFromPresistance<User> _userFetcher;
public static IList<User> GetMatching(Specification<User> spec) {
var values = _userFetcher.Find(spec); //Returns a DataRow or IDictionary<string, object>
return new User() {
PhoneNumber = new PhoneNumber(values["phone"].ToString()),
Name = values["name"].ToString(),
};
}
}

Categories