Abstract factory bad design? - abstract-factory

I have car factories that build cars of different sizes.
I have 2 factories: USA and Thailand that make car sizes Big, Middle, and Little.
But I have a problem: the Thailand factory does not make big cars.
Code:
public enum CarSize { Big, Middle, Little,}
public interface ICarFactory {
ICar CreateCar(CarSize carSize);
}
public class USACarFactory : ICarFactory {
public ICar CreateCar(CarSize carSize) {
ICar car = null;
switch (carSize) {
case CarSize.Little:
car = new USALittleCar();
break;
case CarSize.Middle:
car = new USAMiddleCar();
break;
case CarSize.Big:
car = new USABigCar();
break;
}
return car;
}
}
public class ThailandCarFactory : ICarFactory {
public ICar CreateCar(CarSize carSize){
ICar car = null;
switch (carSize) {
case CarSize.Little:
car = new ThailandLittleCar();
break;
case CarSize.Middle:
car = new ThailandMiddleCar();
break;
case CarSize.Big:
//no big cars in Thailand!!!!
break;
}
return car;
}
}
public interface ICar { }
public class USABigCar : ICar { }
public class USAMiddleCar : ICar { }
public class USALittleCar : ICar { }
public class ThailandMiddleCar : ICar { }
public class ThailandLittleCar : ICar { }
What should I do?
Is my Abstract Factory poorly designed?

#zzfima, picking up the idea from COM, how about querying the interface and find out it if supports creating car of a specified size and invoke suitably? The code definitely realizes the abstract factory pattern.

case CarSize.Big:
car = new ThailandBigCar();
break;
Try that. That should allow you to make big cars.
public interface ICar { }
public class USABigCar : ICar { }
public class USAMiddleCar : ICar { }
public class USALittleCar : ICar { }
public class ThailandMiddleCar : ICar { }
public class ThailandLittleCar : ICar { }
public class ThailandBigCar : ICar { }

Related

Custom Function to retrieve data from user table

I want a write a custom function to find a particular property from identity user model.
Say I want to find a user with a specified phone number.
How to do so..???
You need to extend the UserStore class, something like below
public interface IUserCustomStore<TUser> : IUserStore<TUser, string>, IDisposable where TUser : class, Microsoft.AspNet.Identity.IUser<string>
{
Task<TUser> FindByPhoneNumberAsync(string phoneNumber);
}
namespace AspNet.Identity.MyCustomStore
{
public class UserStore<TUser> : Microsoft.AspNet.Identity.EntityFramework.UserStore<TUser>, IUserCustomStore<TUser>
where TUser : Microsoft.AspNet.Identity.EntityFramework.IdentityUser
{
public UserStore(ApplicationDbContext context)
: base(context)
{
}
public Task<TUser> FindByPhoneNumberAsync(string phoneNumber)
{
//Your Implementation
}
}
public class UserStore<TUser> : IUserCustomStore<TUser> where TUser:IdentityUser
{
public virtual Task<TUser> FindByPhoneNumberAsync(string phoneNumber)
{
return _Users.Find(u => u.PhoneNumber == phoneNumber).FirstOrDefaultAsync();
}
}
}
Replace all occurrence of
using Microsoft.AspNet.Identity.EntityFramework
with
using AspNet.Identity.MyCustomStore
And then in the IdentityConfig.cs add a new method to ApplicationUserManager
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
//LEAVE ALL THE METHODS AS IT IS
public virtual Task<ApplicationUser> FindByPhoneNumberUserManagerAsync(string phoneNumber)
{
IUserCustomStore<ApplicationUser> userCustomStore = this.Store as IUserCustomStore<ApplicationUser>;
if (phoneNumber == null)
{
throw new ArgumentNullException("phoneNumber");
}
return userCustomStore.FindByPhoneNumberAsync(phoneNumber);
}
}
You can now call this in the controller like
var user = await UserManager.FindByPhoneNumberUserManagerAsync(model.phoneNumber);
(assuming you have added the phoneNumber property to RegisterViewModel)
Hope this helps.

Inheritance Generic Invariance C#4

I've been searching why this generic contruction doesn't compile
I get:
Cannot implicitly convert type 'WpfApplication1.CowDao' to 'WpfApplication1.Dao'
public abstract class Animal { }
public class Dog : Animal { }
public class Cow : Animal { }
public abstract class Dao<T> where T : Animal
{
public void Insert(T t);
}
public class DogDao : Dao<Dog> { }
public class CowDao : Dao<Cow> { }
public class Main
{
public Main()
{
Dao<Animal> dao = null;
if (true) dao = new DogDao();
else dao = new CowDao();
}
}
I just want to get to my goal --> making a 'neutral' instance
I think that my construction has to change, but i don't know how
I'm using .NET Framework 4
Thanks
Generics from a derived does not inherit from Generic from a base class so you may not cast one to another. Instead, write an extension method ToGenericParent that converts like that:
public static Generic<Parent> ToGenericParent(this Generic<Derived> derived)
{
return new Generic<Parent>() { Value = derived.Value };
}
Change your Inheritance for your Dao layers as
public class DogDao : Dao<Animal> { }
public class CowDao : Dao<Animal> { }
Edit:
public abstract class Dao<T> where T : Animal
{
public virtual void Insert(T t)
{
}
protected void ExecuteQuery(string quer)
{
}
}
public class DogDao : Dao<Dog>
{
public override void Insert(Dog t)
{
string insert = "INSERT INTO DOG ...";
base.ExecuteQuery(insert);
}
}
public class CowDao : Dao<Cow>
{
public override void Insert(Cow t)
{
string insert = "INSERT INTO COW ...";
base.ExecuteQuery(insert);
}
}

Repository that accesses multiple tables

This model is simplified, only used for demonstration.
In my application got:
Data
public class Product
{
public Guid Id { get; set; }
public string Name { get; set; }
public Category Category { get; set; }
}
public class Category
{
public Guid Id { get; set; }
public string Name { get; set; }
}
Repository
public interface IRepository<T>
where T : class
{
T Add(T entity);
T Remove(T entity);
IQueryable<T> GetAll();
int Save();
}
public class ProductRepository : IRepository<Product>
{
public Product Add(Product entity) { ... }
public Product Remove(Product entity) { ... }
public IQueryable<Product> GetAll() { ... }
public int Save() { ... }
}
public class CategoryRepository : IRepository<Category>
{
public Category Add(Category entity) { ... }
public Category Remove(Category entity) { ... }
public IQueryable<Category> GetAll() { ... }
public int Save() { ... }
}
Services
public interface ICategoryService
{
Category Add(Guid gidProduct, Category category);
}
public class CategoryService : ICategoryService
{
public Category Add(Guid gidProduct, Category category){ ... } //Problem here
readonly IRepository<Category> _repository;
public CategoryService(IRepository<Category> repository) //Problem here
{
_repository = repository;
}
}
As I have a repository for each class when I need information from another repository in my service, what should I do?
In the example above, in my service layer I have a method to Add a product (where I found the code for it) and a category.
The problem is that I do a search in the repository of products to recover it, but in my service class category, there is no repository of products., how to solve this problem?
First you need to create a repository for each aggregate root not for each class.
and if you need to access more than one repository in your service, simply you depend on all of them then you can add them as parameters to the constructor for dependency injection.
public CategoryService(CategoryRepository categoryRepository, ProductRepository productRepository)
{
_categoryRepository = categoryRepository;
_productRepository = productRepository;
}

How to define a constraint on class type if It has custom attribute?

there is any way to force a class to implement an interface , if It has an specific custom attribute?
I want to have a compile time error , if the class with specific attribute does not implement an specific interface.
[myAttrib]
public MyClass:IMyInterface
{
}
If myClass is not typeof(IMyInterface) , I will get an error in compile time.
thanks,
In case of properties, You could create an abstract class inheriting the interface and gets your final class drive from that abstract class.
Have a look at
public interface Test
{
string Name { get; set; }
}
public abstract class Test1 : Test
{
public abstract string Name { get; set; }
}
public class Test2 : Test1
{
}
For custom attribute you could do
public class Alias : System.Attribute
{
string[] _types;
public Alias(params string[] types)
{
this.Types = types;
}
public Alias()
{
this.Types = null;
}
public string[] Types
{
get { return _types; }
set { _types = value; }
}
}
public interface Test
{
Alias Attrib{ get;}
}
public abstract class Test1 : Test
{
public abstract Alias Attrib { get; }
}
public class Test2 : Test1
{
}
Hope I answer your question.

Code Contracts: How to deal with inherited interfaces?

I'm using MS Code Contracts and have run into a snag with using interface inheritance and ContractClassFor attributes.
Given these interfaces and contract classes:
[ContractClass(typeof(IOneContract))]
interface IOne { }
[ContractClass(typeof(ITwoContract))]
interface ITwo : IOne { }
[ContractClassFor(typeof(IOne))]
abstract class IOneContract : IOne { }
[ContractClassFor(typeof(ITwo))]
abstract class ITwoContract : IOneContract, ITwo { }
Let's say that IOne and ITwo are substantial interfaces. So IOneContract would have a significant amount of code in it for the necessary checks.
I don't want to duplicate all of that in ITwoContract for the IOne interfaces. I only want to add new contracts for the ITwo interfaces. Inheriting one contract class from another seems the likely way to reuse that code. Yet I get the following error:
EXEC : warning CC1066: Class 'ITwoContract' is annotated as being the contract for the interface 'ITwo' and cannot have an explicit base class other than System.Object.
Is this a limitation in Code Contracts or am I doing it wrong? We have a lot of interface inheritance in our project and this feels like a deal breaker for Code Contracts if I can't figure out how to work around this issue.
Instead of:
[ContractClassFor(typeof(ITwo))]
abstract class ITwoContract : IOneContract, ITwo { }
Just inherit the contract:
[ContractClassFor(typeof(ITwo))]
abstract class ITwoContract : ITwo { }
You only need to provide contracts on the methods which are new in ITwo. The contracts from IOneContract will be inherited automatically, and you can declare all the inherited IOne methods as abstract — in fact, you cannot provide contracts for IOne on ITwoContract, or CC will complain :)
For example, if you have this:
[ContractClass(typeof (IOneContract))]
interface IOne
{
int Thing { get; }
}
[ContractClass(typeof (ITwoContract))]
interface ITwo : IOne
{
int Thing2 { get; }
}
[ContractClassFor(typeof (IOne))]
abstract class IOneContract : IOne
{
public int Thing
{
get
{
Contract.Ensures(Contract.Result<int>() > 0);
return 0;
}
}
}
[ContractClassFor(typeof (ITwo))]
abstract class ITwoContract : ITwo
{
public int Thing2
{
get
{
Contract.Ensures(Contract.Result<int>() > 0);
return 0;
}
}
public abstract int Thing { get; }
}
Then this implementation will say "unproven contract" on both methods, as expected:
class Two : ITwo
{
public int Thing
{
get { return 0; }
}
public int Thing2
{
get { return 0; }
}
}

Resources