How do I refactor two classes with similar functionality? - c++11

I have classes with methods with the same names that do the same thing yet they are implemented differently.
Ex:
class converterA {
map(Item1 item1) {
// Implementation details.
}
convert(Item1 item1) {
// Implementation details.
}
translate(Item1 item1) {
// Implementation details.
}
}
class converterB {
map(Item2 item2) {
// Implementation details.
}
convert(Item2 item2) {
// Implementation details.
}
translate(Item2 item2) {
// Implementation details.
}
}
I considered using an interface but the issue is that is that the methods take in different parameters. Yet a template doesn't exactly fit either because Item1 and Item2 operate in different ways. In other words, they don't have common methods so a template doesn't exactly fit either.
Is there a solution here for refactoring the code?

Given your comment "way to... have an interface styled class that can be extended", you might be interested in using templates to express the common "interface":
template <typename Item>
struct Converter
{
virtual void map(Item) = 0;
virtual void convert(Item) = 0;
virtual void translate(Item) = 0;
};
class converterA : public Converter<Item1> {
void map(Item1 item1) final { ... }
void convert(Item1 item) final { ... }
void translate(Item1 item) final { ... }
};
class converterB : public Converter<Item2> {
...same kind of thing...
};
All it buys you though is an expression of the "Converter" interface they share, some compile-time enforcement that the function signatures and names match that (e.g. if you change Converter<> you'll be reminded to update all the derived types), and the ability to handle the derived classes using pointer/references to the template instantiations they derive from (which is not of any ostensible use to you).

I was thinking about using template specialization, but if they both use totally different methods it's not really worth it, although it would be more readable.

Related

Overcomplicating design patterns

I am trying to solve a design problem with design patterns. Now that I have the basics I am fairly sure that I overcomplicated it a lot. I seem to have multiple empty interfaces, and I probably could do with less with a different design. Also I'm not sure if future developers on the project will have an easy time figuring out this tangle.
I've made a mockup of the structure of the classes. The example is dumbed down to two service types (cf BaseAnimalService extensions), in the project there are more. There are also more BaseStrategy implementations.
At first I want do differentiate between a context for a CatService or DogService. This is done using a Map in the BaseStrategy class, which has the BaseAnimalService as value to enable polymorphism between the Cat/DogService. Based on the generic type of the BaseStrategy, implemented in the Dog/CatStrategy a different configurationMap is used, which in turn, based on the type of the criteria, loads one or the other implementation of the Dog/CatService.
The configuration maps are defined in the spring.xml file.
Since the Dog/CatService both implement an extra interface, cf. SomeOtherCat/DogService, which is external to my design, the Dog/CatService both have have empty interfaces too. SomeOtherCatService and SomeOtherDogService aren't related and aren't editable so I can't use them polymorphically, which is the reason for the Base/Cat/DogService interfaces.
I thought about making the BaseStrategy a StrategyFactory which returns a Cat/DogStrategy which in turn checks the type of the criteria for which BaseAnimalService to use. But since both these strategies use the same logic for their strategies, this would mean I would have to create another base class.
What do you think? Any suggestions on what would be a better design for this problem? Or any improvements to the current one?
class BaseStrategy<T extends BaseAnimalService> {
private ContextService contextService;
private Map<String, BaseAnimalService> configurationMap;
T getService() {
return configurationMap.get(contextService.getCurrentContext());
}
}
interface BaseAnimalService {
//empty
}
interface DogService extends BaseAnimalService {
//empty
}
interface CatService extends BaseAnimalService {
//empty
}
class DogStrategy extends BaseStrategy<DogService> {
//empty
}
class CatStrategy extends BaseStrategy<CatService> {
//empty
}
class BritishShortHairServiceImpl implements CatService, SomeOtherCatService {
#Override //source: SomeOtherCatService, same for other implementations below
void pur() {
//pur
}
}
class LionServiceImpl implements CatService, SomeOtherCatService {
#Override
void pur() {
//pur
}
}
class PitBullServiceImpl implements DogService, SomeOtherDogService {
#Override
void wagTail() {
//wag tail
}
}
class ChihuahuaServiceImpl implements DogService, SomeOtherDogService {
#Override
void wagTail() {
//wag tail
}
}
class CatPerson {
private BaseStrategy<CatService> catStrategy;
void pet() {
catStrategy.getService().pur();
}
}
class DogPerson {
private BaseStrategy<DogService> dogStrategy;
void feed() {
dogStrategy.getService().wagTail();
}
}
Relevant spring.xml snippet:
<bean id="baseStrategy" abstract="true"
class="com.animals.services.BaseStrategy">
<property name="contextService" ref="contextService"/>
</bean>
<bean id="catServiceStrategy"
class="com.animals.services.CatStrategyImpl"
parent="baseStrategy">
<property name="strategyConfigurationMap">
<map>
<entry key="CONTEXT1" value-ref="britishShortHairService"/>
<entry key="CONTEXT2" value-ref="lionService"/>
</map>
</property>
</bean>
<bean id="dogServiceStrategy"
class="com.animals.services.DogStrategyImpl"
parent="baseStrategy">
<property name="strategyConfigurationMap">
<map>
<entry key="CONTEXT1" value-ref="pitbullService"/>
<entry key="CONTEXT2" value-ref="chihuahuaService"/>
</map>
</property>
</bean>
I am not familiar with Spring or its Context Service model, so I am approaching this question from a general, language-independent OOP perspective.
In my opinion you need to be thinking about ways that you can pass configurations through the constructor (dependency injection) rather than switching based on maps. You need more "has a" relationships (composition) and less "is a" relationships (inheritance).
An AnimalService can take an animal object as an argument to the constructor. We can say that an AnimalFeedbackBehavior must include methods for positiveFeedback(), neutralFeedback(), and negativeFeedback() -- but how those methods are implemented can vary from animal to animal. A Cat would purr() in response to a positive interaction but a Dog would wagTail().
An AnimalOwner can feed() any animal and trigger AnimalFeedbackBehavior.positiveFeedback(). The AnimalOwner does not need to know what that behavior does behind the scenes. It does not even need to know what species of animal it has. All it needs to know is that this method exists.
interface AnimalFeedbackBehavior {
positiveFeedback(): void;
neutralFeedback(): void;
negativeFeedback(): void;
}
class AnimalOwner {
private animal: AnimalFeedbackBehavior;
// pass animal instance to the constructor
constructor( animal: AnimalFeedbackBehavior) {
this.animal = animal;
}
// trigger positive feedback when feeding
feed() {
this.animal.positiveFeedback();
}
}
class Cat implements AnimalFeedbackBehavior {
purr() {
//do something
}
positiveFeedback() {
this.purr();
}
/* ... rest of class ... */
}
Typescript Playground Link
Here we assumed that feed is always a positive interaction. But what if we want different animals to have different reactions to the same interactions? chase() might be positive for a Dog but negative for a Cat. A naïve approach would be to switch the feedback based on a map. But an ideal design allows for maximum abstraction where the AnimalOwner doesn't need to know anything about the animal types.
Let's try a totally different setup.
If you are dealing with a small set of behaviors, we could require that the animal has a response for each behavior, rather than positive/neutral/negative.
interface AnimalBehavior {
feedResponse(): void;
chaseResponse(): void;
}
But this could get unwieldy quickly. We could define an animal with a respond method that responds to some sort of generic action object. In the implementation, it can do something in response to the action or just ignore it.
This setup also makes the composition of multiple overriding behaviors more intuitive since we can go through a chain of respond functions until one handles it. We want to know it there was a response or not so we need to return something from the response function. If it's basically void then we can return a boolean flag that's true if it responded. If a response should return a value than you would return either that value or undefined.
interface Action {
type: string;
}
// we may want to attach some sort of data
interface ActionWithData<T> extends Action {
type: string;
data: T;
}
interface AnimalBehavior {
respond( action: Action ): string | undefined;
}
class Animal implements AnimalBehavior {
// an animal has an array of behavior responders
// as written, the earlier behaviors in the array override later ones
private behaviors: AnimalBehavior[];
// can instantiate an animal with multiple behaviors
constructor( behaviors: AnimalBehavior[] = [] ) {
this.behaviors = behaviors;
}
// can also add behaviors after the fact
public addOverride( behavior: AnimalBehavior ) {
this.behaviors = [behavior, ...this.behaviors];
}
// loop through behaviors until one responds
public respond (action: Action): string | undefined {
for ( let element of this.behaviors ) {
// could be a response or might be undefined
const response = element.respond(action);
if ( response ) {
return response;
}
}
// could do something here if no behaviors responded
return undefined;
}
}
class AnimalOwner {
private animal: AnimalBehavior;
// pass animal instance to the constructor
constructor( animal: AnimalBehavior) {
this.animal = animal;
}
// animal can respond to the feed action, or not
feed(): string | undefined {
return this.animal.respond({type: 'feed'});
}
chase(): string | undefined {
return this.animal.respond({ type: 'chase' });
}
}
These implementations feel sloppy at the moment. Right now none of them use this so it's pointless to use a class. But just to give you an idea:
class DogBehavior implements AnimalBehavior {
respond(action: Action): string | undefined {
switch (action.type) {
case 'feed':
return "Wag Tail";
case 'chase':
return "Run Around";
default:
return undefined;
}
}
}
class PuppyBehavior implements AnimalBehavior {
respond(action: Action): string | undefined {
switch (action.type) {
case 'feed':
return "Jump";
default:
return undefined;
}
}
}
class ChihuahuaBehavior implements AnimalBehavior {
respond(action: Action): string | undefined {
switch (action.type) {
case 'feed':
return "Yip";
default:
return undefined;
}
}
}
Both the Animal composition and the individual behaviors implement AnimalBehavior, so an AnimalOwner can take a DogBehavior directly or it can take an Animal composed of a DogBehavior and some other behaviors.
const owner1 = new AnimalOwner(new DogBehavior());
let res = owner1.feed(); // is "Wag Tail"
The order matters. If we have a chihuahua puppy, we need to decide whether ChihuahuaBehavior overrides PuppyBehavior or vice-versa.
// prioritizes puppy
const owner2 = new AnimalOwner(new Animal([new PuppyBehavior(), new ChihuahuaBehavior(), new DogBehavior()]));
res = owner2.feed(); // is "Jump" from PuppyBehavior
res = owner2.chase(); // is "Run Around" from DogBehavior because not overwritten
// prioritizes chihuahua
const owner3 = new AnimalOwner(new Animal([new ChihuahuaBehavior(), new PuppyBehavior(), new DogBehavior()]));
res = owner3.feed(); // is "Yip" from ChihuahuaBehavior
Typescript Playground Link

Mocking Static Method in c++

I just started working on unit testing using googleTest.
I have a situation where I have a static method of one class is calling inside the other class
class A {
public:
static bool retriveJsonData(std::string name, Json::Value& responseJsonData);
}
In other class i am using the Class A retriveJsonData method.
class B {
public:
bool Method1 (std::string name) {
Json::Value sampleJsonData;
return A::retriveJsonData(name, sampleJsonData);
}
Mocking of class A
class MockA : public A {
public:
MOCK_MEHTOD2(retriveJsonData, bool(std::string, Json::Value));
}
Now I have to mock retriveJsonData in Testing of Method2 of class B using EXPECT_CALL.
Please help me to resolve how can I test this situation?
Google Mock's mock types provide ways to check expected calls for non-static member functions, where either virtual function polymorphism or templates can be used as a "seam" to swap in the mock functions for real functions. Which is great if you can design or refactor everything to use one of those techniques. But sometimes it would be cumbersome to get things working that way in messy legacy code or in code using an external library, etc.
In that case, another option is to define a dependency function which is not a non-static member function (so either a free function or a static member) to redirect to some singleton mock object. Assume we have some translation unit (B.cpp) to be unit tested, and it calls some non-member or static member function (A::retrieveJsonData) not defined in that translation unit.
Normally, to unit test B.cpp, we would note its required linker symbols and provide fake definitions for them that stub them out, just to get the object file B.o to link into the unit test program:
// Fake definition:
bool A::retrieveJsonData(std::string, Json::Value&)
{ return false; }
In this case, we don't want that fake definition; we'll define it later to redirect to a mock object.
Start with a mock class specifically for the problematic function calls. If there are other non-static member functions to test the ordinary way, this class is NOT the same as those classes. (If this is needed for more than one function, these mock classes could be done per function, per class and/or one for free functions, per library, one for everything; however you want to set it up.)
class Mock_A_Static {
public:
Mock_A_Static() {
EXPECT_EQ(instance, nullptr);
instance = this;
}
~Mock_A_Static() {
EXPECT_EQ(instance, this);
instance = nullptr;
}
MOCK_METHOD2(retrieveJsonData, bool(std::string, Json::Value&));
private:
static Mock_A_Static* instance;
friend class A;
};
Mock_A_Static* Mock_A_Static::instance = nullptr;
// The function code in B.cpp will actually be directly calling:
bool A::retrieveJsonData(std::string name, Json::Value& responseJsonData)
{
EXPECT_NE(Mock_A_Static::instance, nullptr)
<< "Mock_A_Static function called but not set up";
if (!Mock_A_Static::instance) return false;
return Mock_A_Static::instance->retrieveJsonData(name, responseJsonData);
}
Then just put an object of that type local to a test, or in a fixture class. (Only one at a time, though!)
TEST(BTest, Method1GetsJson)
{
Mock_A_Static a_static;
B b;
EXPECT_CALL(a_static, retrieveJsonData(StrEq("data_x"), _));
b.Method1("data_x");
}
Use A as a template parameter in class B (see Modern C++ Design).
template <class T>
class B {
public:
bool Method1 (std::string name) {
Json::Value sampleJsonData;
return T::retriveJsonData(name, sampleJsonData);
}
}
then in your tests use:
B<MockA> b;
In production code:
B<A> b;
You can't use MOCK_MEHTOD2 with static methods.
You can define a private method in B that just call retriveJsonData:
Class B
{
public:
bool Method1 (std::string name) {
Json::Value sampleJsonData;
return retriveJsonData(name, sampleJsonData); };
private:
bool retriveJsonData(std::string name, Json::Value& responseJsonData) {
return A::retriveJsonData(name, responseJsonData); };
};
Then you can write a test class to be used in your test instead of B:
Class Test_B : public B
{
MOCK_METHOD2( retriveJsonData, bool(std::string name, Json::Value& responseJsonData));
};
This situation is very common in real development. To isolate a target class the gmock is very useful but also very limitted.
However, if you don't want to change any of the class A and B, here is the one of the solution by using "jomock" without changing A and B at all.
// let's say there are class A and B in legacy code.
class A {
public:
static bool retriveJsonData(std::string name, Json::Value& responseJsonData);
}
class B {
public:
bool Method1 (std::string name) {
Json::Value sampleJsonData;
return A::retriveJsonData(name, sampleJsonData);
}
// unit test code below
#include "jomock.h"
TEST(JoMock, staticFnTest)
{
EXPECT_CALL(JOMOCK(A::retriveJsonData), JOMOCK_FUNC(_,_))
.Times(Exactly(1))
.WillOnce(Return(false)); // return false once.
EXPECT_EQ(B::Method1("arg"), false);
}

The fact that the type of function determined in runtime is defined as advantage?

I read that one advantage of using by "inheritance" for generic-code is "the fact that the type of the object determined in runtime", because that allows more flexibility.
I don't understand this point. How it's really allows more flexibility?
If for example I get object from type that derived Base , so that:
class Base{
public:
virtual void method() const { /* ... */ }
};
class D1 : public Base{
public:
void method() const override { /* ... */ }
};
class D2 : public Base{
public:
void method() const override { /* ... */ }
};
And I send to function f (for example) the following object:
Base* b = new D1;
f(b);
Where is the flexibility (What it's defined as advantage that it's done in runtime) ?
Your example isn't demonstrating it, but it could.
f(b) could be
void f(Base* b) {
b->method();
}
Now, the actual method() code that's executed is determined at runtime by the type of the object that's passed in.
How it's really allows more flexibility?
It's more flexible because the author of f(..) doesn't need to know how Base:method() works in any specific case: You can add D3, D4, D5 classes with new implementations of method() without f(..) ever needing to know or change.

java prevent a lot of if and replace it with design pattern(s)

I use this code in my application and I find it very ugly.
Is there a smart way of doing this?
for (final ApplicationCategories applicationCategorie : applicationCategories) {
if (applicationCategorie == ApplicationCategories.PROJECTS) {
// invoke right method
} else if (applicationCategorie == ApplicationCategories.CALENDAR) {
// ...
} else if (applicationCategorie == ApplicationCategories.COMMUNICATION) {
} else if (applicationCategorie == ApplicationCategories.CONTACTS) {
} else if (applicationCategorie == ApplicationCategories.DOCUMENTS) {
} else if (applicationCategorie == ApplicationCategories.WORKINGBOOK) {
}
}
My aim is to handle all application categorie enums which contained into the enum list.
The least you can do is to declare the method that handles the behaviour dependent to the enum inside ApplicationCategories. In this way, if you will add a new value to the enum, you will only to change the code relative to enum.
In this way, your code adheres to the Open Closed Principle, and so it is easier to maintain.
enum ApplicationCategories {
PROJECTS,
CALENDAR,
// And so on...
WORKINGBOOK;
public static void handle(ApplicationCategories category) {
switch (category) {
case PROJECTS:
// Code to handle projects
break;
case CALENDAR:
// Code to handle calendar
break;
// And so on
}
}
}
This solution is only feasable if you do not need any external information to handle the enum value.
Remember you can also add fields to enum values.
EDIT
You can also implement a Strategy design pattern if you need. First of all, define a strategy interface and some concrete implementations.
interface CategoryStrategy {
void handle(/* Some useful input*/);
}
class ProjectStrategy implements Strategy {
public void handle(/* Some useful input*/) {
// Do something related to projects...
}
}
class CalendarStrategy implements Strategy {
public void handle(/* Some useful input*/) {
// Do something related to calendars...
}
}
//...
Then, you can modify your enum in order to use the above strategy.
enum ApplicationCategories {
PROJECTS(new ProjectStrategy()),
CALENDAR(new CalendarStrategy()),
// And so on...
WORKINGBOOK(new WorkingBookStrategy());
private CategoryStrategy strategy;
ApplicationCategories(CategoryStrategy strategy) {
this.strategy = strategy;
}
public static void handle(ApplicationCategories category) {
category.strategy.handle(/* Some inputs */);
}
}
Clearly, the above code is only a sketch.
The design pattern you need is the Strategy.
Enums and violation of the Open/Closed Principle
The use of enums when you have to perform a different action for each defined value is a bad practice. As the software evolves, it is likely that you have to spread the if chain around different places. If you add a new enum value, you'll have to add a new if for that value in all these places. Since you may not even be able to find all the places where you have to include the new if, that is a source for bugs.
Such approach also violates the Open/Closed Principle (OCP). Just creating a method to handle each enum value doesn't make your code conformant to OCP. It will make the code more organised but doesn't change anything about the "if" issue.
Java 7 solution with Strategy Pattern
Using Java 7 or prior, you can define a ApplicationCategory interface that all categories will implement. This interface will provide a common method that each category will implement to perform the required actions for that category:
public interface ApplicationCategory {
boolean handle();
}
Usually your method should return something. Since I don't know what is your exact goal, I'm making the method to return just a boolean. It would indicate if the category was handled or not, just as an example.
Then you have to define a class implementing such an interface for each category you have. For instance:
public class CalendarCategory implements ApplicationCategory {
boolean handle(){
//the code to handle the Calendar category
return true;
}
}
public class CommunicationCategory implements ApplicationCategory {
boolean handle(){
//the code to handle the Communication category
return true;
}
}
Now you don't need the enum class and the handle method that was inside it needs to be moved elsewhere, that completely depends on your project. That handle method will be changed to:
public static void handle(ApplicationCategory category) {
//Insert here any code that may be executed,
//regardless of what category it is.
category.handle();
}
You don't need an enum anymore because any variable declared as ApplicationCategory just accepts an object that implements such an interface. If you use the enum together with the Strategy implementation, it will be yet required to change the enum class any time you add a new ApplicationCategory implementation, violating the OCP again.
If you use the Strategy pattern, you don't even need the enum anymore in this case.
Java 8 solution with functional programming and Strategy Pattern
You can more easily implement the Strategy pattern using functional programming and lambda expressions, and avoid the proliferation of class just to provide different implementations of a single method (the handle method in this case).
Since the handle method is not receiving any parameter and is retuning something, this description conforms to the Supplier functional interface. An excellent way to identify what kind of functional interface a method you are defining conforms to, it is studying the java.util.function package.
Once the type of functional interface is identified, we can create just a ApplicationCategory class (that in the Java 7 example was an interface) in a functional way, defining the previous handle method as an attribute of the Supplier type. You must define a setter for this handle attribute to enable changing the handle implementation. Defining a method as an attribute, you are enabling such a method implementation to be changed in runtime, providing a different but far simpler, easier and more maintainable implementation of the Strategy pattern.
If you need to use the category name somewhere, for instance to display it in a user interface, you could define an enum inside the ApplicationCategory class. However, there is no direct relation between the enum value and the handle provided. The enum works just as a tag for the category. It is like a "name" attribute in a Person class, that we usually just use to "tag" and print a person.
public class ApplicationCategory {
//insert all categories here
enum Type {CALENDAR, COMMUNNICATION}
/**
* The Supplier object that will handle this category object.
* It will supply (return) a boolean to indicate if the category
* was processed or not.
*/
private Supplier<Boolean> handler;
private Type type;
/**
* A constructor that will receive a Supplier defining how to
* handle the category that is being created.
*/
public ApplicationCategory(Type type, Supplier<Boolean> handler){
Objects.requireNonNull(type);
this.handler = handler;
setType(type);
}
/**
* Handle the category by calling the {#link Supplier#get()} method,
* that in turn returns a boolean.
*/
public boolean handle(){
return supplier.get();
}
public Type getType(){ return type; }
public final void setHandler(Supplier<Boolean> handler){
Objects.requiredNonNull(handler);
this.handler = handler;
}
}
If you give the behaviour that will handle the enum value at the enum constructor call, as suggested by the other answer provided here, then you don't have how to change the behaviour in runtime and it in fact doesn't conform to the Strategy pattern. Unless you really don't need that, you might implement in that way, but remember it violates the OCP.
How to use the Java 8 functional ApplicationCategory class
To instantiate a ApplicationCategory you have to provide the Type (an enum value) and the handler (that is a Supplier and can be given as a lambda expression). See the example below:
import static ApplicationCategory.CALENDAR;
public class Test {
public static void main(String args[]){
new Test();
}
public Test(){
ApplicationCategory cat = new ApplicationCategory(CALENDAR, this::calendarHandler);
System.out.println("Was " + cat + " handled? " + cat.handle());
}
private boolean calendarHandler(){
//the code required to handle the CALENDAR goes here
return true;
}
}
The this::calendarHandler instruction is a method reference to pass a "pointer" to the calendarHandler method. It is not calling the method (you can see that due to the use of :: instead of . and the lack of parenthesis), it is just defining what method has to be in fact called when the handle() method is called, as can be seen in System.out.println("Was " + cat + " handled? " + cat.handle());
By using this approach, it is possible to define different handlers for different instances of the same category or to use the same handler for a subset of categories.
Unlike other languages, Java provides facilities that specifically allow this sort of thing to be done in a safe object-oriented way.
Declare an abstract method on the enum, and then specific implementations for each enum constant. The compiler will then ensure that every constant has an implementation and nobody has to worry about missing a case somewhere as new values are added:
enum ApplicationCategories {
PROJECTS {
void handle() {
...
}
},
...
public abstract void handle();
}
Then, instead of calling some static handle(category), you just call category.handle()

Where do I add a behavior to a single Region?

My problem is very simple, but all the options confuse me...
In my MEF/Prism-application, I want to attach a specific behavior to one specific region. The doumentation says, that you can do it that way:
IRegion region = regionManager.Region["Region1"];
region.Behaviors.Add("MyBehavior", new MyRegion());
But where should I put this? Is there some place, this is supposed to be done in a bootstrapper method? Currently, I am adding the behavior like this in the Loaded-event of the shell:
/// <summary>
/// Interaction logic for Shell.xaml
/// </summary>
[Export(typeof(Shell))]
public partial class Shell
{
[ImportingConstructor]
public Shell(IRegionManager regionManager, ElementViewInjectionBehavior elementViewInjectionBehavior)
{
InitializeComponent();
Loaded += (sender, args) =>
{
IRegion region = regionManager.Regions[RegionNames.ElementViewRegion];
region.Behaviors.Add("ElementViewInjection", elementViewInjectionBehavior);
};
}
}
Is this a good solution. I'd rather do it in the bootstrapper, so that it is done in the same place as the other region behavior registrations (ConfigureDefaultRegionBehaviors()).
So, the question: Where is the best place to add the behavior to one single region?
I just came up with a slightly improved solution, using a static string collection in the behavior to add the regions to attach the behavior to.
public class ViewModelInjectionBehavior : RegionBehavior, IDisposable
{
private static List<string> _regionNames;
public static List<string> Regions
{
get { return _regionNames ?? (_regionNames = new List<string>()); }
}
protected override void OnAttach()
{
if (Regions.Contains(Region.Name)) {...}
}
}
Then in my bootstrapper, I can define the regions:
protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
{
var behaviorFactory = base.ConfigureDefaultRegionBehaviors();
ViewModelInjectionBehavior.Regions.Add(RegionNames.ElementViewRegion);
behaviorFactory.AddIfMissing("ElementViewInjectionBehavior", typeof(ViewModelInjectionBehavior));
return behaviorFactory;
}
At least, the behavior is universally usable now...
We had the same issue - in the end we just checked the region name in the region behaviour and acted only if it was that region that we wanted, kind of sucks because you are attaching the behaviour to all regions - but for us it was better than the suggested solution..
An example looks like :
public class TrackViewOpenerBehaviour : IRegionBehavior
{
public IRegion Region { get; set; }
public void Attach()
{
if (this.Region.Name == ApplicationRegions.WorkspaceRegion
|| this.Region.Name == ApplicationRegions.DialogRegion)
{
this.Region.Views.CollectionChanged += (sender, e) =>
{
//Code Here.
};
}
}
}
I always thought maybe we could create a behaviour that was responsible for attaching other behaviours to specfiic regions for us, then we could register that in the bootstrapper - but never got round to it.

Resources