Skip to content

Instantly share code, notes, and snippets.

@darrencauthon
Created February 23, 2015 14:58
Show Gist options
  • Save darrencauthon/6f2fd7c86c54ab6a585d to your computer and use it in GitHub Desktop.
Save darrencauthon/6f2fd7c86c54ab6a585d to your computer and use it in GitHub Desktop.
Good and Evil (?)
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
// etc
public IQueryable<Product> All()
{
MyIoCContainer.Resolve<DbContext>().Products();
}
}
public class ProductController
{
public ActionResult Index()
{
return ActionView("Index", Product.All());
}
}
MyIoCContainer.Register<DbContext>(() => new DbContext());
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
// etc
}
public class IProductRepository
{
IQueryable<Product> All();
}
public class ProductRepository :: IProductRepository
{
private DbContext dbContext;
public ProductRepository(DbContext dbContext)
{
this.dbContext = dbContext
}
public IQueryable<Product> All()
{
dbContext.Products();
}
}
public class ProductController
{
private IProductRepository productRepository;
public ProductController(IProductRepository productRepository)
{
this.productRepository = productRepository;
}
public ActionResult Index()
{
return ActionView("Index", productRepository.All());
}
}
MyIoCContainer.Register<IProductRepository, ProductRepository>();
MyIoCContainer.Register<DbContext>(() => new DbContext());
@darrencauthon
Copy link
Author

1.) I think we're trading a lot of time/money to uphold our ideals of "good design" in C#. There is some payoff with making everything a composable part... whether it be abstracting out the framework-provided System.DateTime.Now() or a product repository.

Code is code is code. I like the "good" section here as a bunch of parts that can easily be replaced, and the Darren of 3.5 years ago would look at the "evil" code and say "NO WAY."

But I should point out that in other langauges, stacks, frameworks... people ARE coding the "evil" way. And their code is fully tested, and it works, and parts are still easily swappable, and SRP is maintained.

2.) C# is evolving and changing, to the point that faking statics & non-virtual methods are no longer the sphere of third-party libraries... it's now available in the base framework with System.Fakes.

In a language like Ruby, I'll call Time.now in my TDD process without skipping a beat. Now, .now is not a static call in Ruby, of course... Time is an object just like any other object. I'll also attach methods on core objects like Product because... there's no real need for the ProductRepository, as the one line of code is the same whether-or-not I wrap it in two abstract types.

For a long, long time, this was not possible in C# due to the nature of the language... but as C# evolves, I think we should reconsider some things we accept as true. Especially if those things cost us time/money.

3.) A few years in Ruby have shown me that the "reach-out" is the same with the instance-of-an-interface-I-created-just-to-abstract-and-test as the original static call.

Take Product.All(). Oh gosh, mind-blown, that's a static call! Now any consumer of Product.All() is not only responsible for doing whatever they are supposed to do, but now they are responsible for knowing how to get products!

So, our solution is.... to create a new type, called IProductRepository, tag it with an All() method, and then have the consumers call it instead.... ignoring the fact that the consumers still have to have knowledge of IProductRepository and All(). Yes, resolving as an interface through an IoC container opens a huge seam that we will probably depend on later... but what if that seam were to exist in other ways?

In Ruby, there are seams on everything. It wasn't that way in C#.... But What if MS Changed That?

Just food for thought. I'm not saying that C# programmers to shift from the "good" design above to the "evil" one, but... perhaps think about it a little bit, look at how others are doing this, and take advantage of all of the new stuff MS is providing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment